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 internals+get-72417@lists.php.net to get a copy of this message
On Sun, Feb 9, 2014 at 2:22 AM, Rowan Collins <rowan.collins@gmail.com>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

« previous php.internals (#72417) next »