Re: [discussion] add array_usearch()

From: Date: Sun, 09 Feb 2014 00:04:30 +0000
Subject: Re: [discussion] add array_usearch()
References: 1 2 3 4  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
On Sun, Feb 9, 2014 at 2:22 AM, Rowan Collins <[email protected]>wrote:

> On 06/02/2014 19:55, Tjerk Meesters wrote:
>
>> Consider the following examples for finding a value in an array:
>>
>> array_search($value, $array, true);
>>
>> current(array_keys($array, $value, true));
>>
>> key(array_filter($array, function($item) use ($value) {
>>      return $item === $value;
>> }));
>>
>> Perhaps I've overlooked one way, but that's already three ways of doing
>> something similar; the difference lies in the memory behaviour, the first
>> being O(1) whereas the other two are O(n).
>>
>
> I was pondering this, and it occurred to me it could actually be cast as
> an application of array_reduce(), except that that function doesn't
> currently provide array keys to the callback function. Assuming a third
> parameter was passed to the callback containing the current key, you could
> define it thus:
>
> function array_usearch($array, $fn) {
>     return array_reduce($array, function(&$result, $value, $key) use ( $fn
> ) {
>         if ( is_null($result) && $fn($value, $key) ) {
>             $result = $key;
>         }
>     });
> }
>
> (The invert flag would make it a little more verbose, but this would be
> enough for parity with array_filter() anyway.)
>
> This would presumably have the same memory profile as a dedicated
> implementation (no array needs to be initialised, only the single return
> value), and the same worst-case time performance, but without the ability
> to short-cut once a match has been found.


> Incidentally, in your proposal, you mentioned this:
>
>
>  [2] the array key is passed as the 2nd argument by using
>> ARRAY_USEARCH_USE_KEY
>>
>
> Is there a particular reason *not* to pass an extra parameter to
> callbacks, even if it's unused?
>

Yeah, internal functions don't like extra parameters, e.g.:

  is_numeric('123', 4);

  > Warning: is_numeric() expects exactly 1 parameter, 2 given in php shell
code on line 1

This would get in the way when you want to express "give the array key of
the first numeric element".


> In the case of an existing function like array_filter(), I can see that
> there is a small risk of a BC break if a function was reused as the
> callback that could optionally take an additional parameter, and relied on
> that parameter not being passed in, but that seems like a bit of an edge
> case anyway, and doesn't apply to a brand new function.
>
>
> Of couse, the proposed function can trivially be implemented with a
> foreach loop as well, even including a short-cut once a match has been
> found:
>
> function array_usearch( $array, $fn ) {
>     foreach ( $array as $k => $v ) {
>         if ( $fn($k, $v) ) {
>             return $k;
>         }
>     }
>     return false;
> }
>

Right; I would personally prefer this over the rather intricate use of
array_reduce() ;-) that said, array_search() and in_array()
can also
be easily implemented in this fashion.


>
> http://codepad.viper-7.com/YM8LSs
>
> Again, I've omitted the ability to invert the matching, but there are
> plenty of efficient ways of adding that.
>
> Regards,
>
> --
> Rowan Collins
> [IMSoP]
>
>
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


-- 
--
Tjerk


Thread (11 messages)

« previous php.internals (#72417) next »