Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:72417 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 20415 invoked from network); 9 Feb 2014 00:04:35 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 9 Feb 2014 00:04:35 -0000 Authentication-Results: pb1.pair.com header.from=tjerk.meesters@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=tjerk.meesters@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.220.177 as permitted sender) X-PHP-List-Original-Sender: tjerk.meesters@gmail.com X-Host-Fingerprint: 209.85.220.177 mail-vc0-f177.google.com Received: from [209.85.220.177] ([209.85.220.177:42336] helo=mail-vc0-f177.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 41/F0-12906-116C6F25 for ; Sat, 08 Feb 2014 19:04:33 -0500 Received: by mail-vc0-f177.google.com with SMTP id if11so3712610vcb.22 for ; Sat, 08 Feb 2014 16:04:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=pUMbppVLL+AD7f90e2ktHjJ/a/IHkt+jrRsPN3NLim0=; b=Z9/+74Mm9WcpkqQIzAUW3vC7MDQ2rpJtTwcjAwrkM3tCzgL4g98Y8yWT4DL/Ne+hut mLvuoCkjm9vNPG6MqElkgC+VJ9AwyR91oU47s4veoYCnTXYYPuN9AgtQepILGhdkrjvU 3/xmSbRkOC0KoMBtdYPeNMSfDExjnXyZzTMZDpnWuRqnLnKnhYvPykhlTCycH4Ez3LS0 eXz2zwTWsX4Wq7dH/TbA4dMSlyQbj/IyrXzoKwqz3ImMNcgoI8cl7Tg1hIQRsg+aBF41 q+uHKeOFEKuWKdoOn+LULuUBalIHEVEOg0kV61/gHu3whQ6TMCy3sEgkHusj2ZrfwSCI XeyA== MIME-Version: 1.0 X-Received: by 10.221.29.137 with SMTP id ry9mr17174989vcb.6.1391904270257; Sat, 08 Feb 2014 16:04:30 -0800 (PST) Received: by 10.58.133.229 with HTTP; Sat, 8 Feb 2014 16:04:30 -0800 (PST) In-Reply-To: <52F675F6.6060800@gmail.com> References: <52F675F6.6060800@gmail.com> Date: Sun, 9 Feb 2014 08:04:30 +0800 Message-ID: To: Rowan Collins Cc: PHP Internals Content-Type: multipart/alternative; boundary=001a1133935c9713f704f1edf7da Subject: Re: [PHP-DEV] [discussion] add array_usearch() From: tjerk.meesters@gmail.com (Tjerk Meesters) --001a1133935c9713f704f1edf7da Content-Type: text/plain; charset=ISO-8859-1 On Sun, Feb 9, 2014 at 2:22 AM, Rowan Collins 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 --001a1133935c9713f704f1edf7da--