Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:89997 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 48850 invoked from network); 4 Jan 2016 18:34:20 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 4 Jan 2016 18:34:20 -0000 Authentication-Results: pb1.pair.com smtp.mail=jbafford@zort.net; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=jbafford@zort.net; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zort.net designates 96.241.205.2 as permitted sender) X-PHP-List-Original-Sender: jbafford@zort.net X-Host-Fingerprint: 96.241.205.2 nova.zort.net Received: from [96.241.205.2] ([96.241.205.2:54451] helo=nova.zort.net) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 6B/27-07292-92BBA865 for ; Mon, 04 Jan 2016 13:34:18 -0500 Received: from [10.0.1.2] (pulsar.zort.net [96.241.205.6]) (authenticated bits=0) by nova.zort.net (8.14.5/8.14.5) with ESMTP id u04IYB64013577 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 4 Jan 2016 13:34:11 -0500 Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) In-Reply-To: Date: Mon, 4 Jan 2016 13:34:10 -0500 Cc: internals@lists.php.net Content-Transfer-Encoding: quoted-printable Message-ID: <9D1F795D-DFDE-4B35-995B-4DE9EC5650E4@zort.net> References: <070A1824-9ED7-4863-92AB-A4366AB92C98@zort.net> To: Andrea Faulds X-Mailer: Apple Mail (2.2104) Subject: Re: [PHP-DEV] Re: [RFC] array_key_(first|last|index) functions proposal From: jbafford@zort.net (John Bafford) Hi Andrea, > On Jan 4, 2016, at 12:05, Andrea Faulds wrote: >=20 > Hi John, >=20 > John Bafford wrote: >> Happy New Year, everyone! >>=20 >> I=E2=80=99d like to present the first new PHP RFC for this year, a = proposal to add functions to easily get the first, last, or an arbitrary = key (and value) by index from an array, taking advantage of PHP=E2=80=99s = property that arrays are ordered maps. >>=20 >> RFC: https://wiki.php.net/rfc/array_key_first_last_index >> PR: https://github.com/php/php-src/pull/347 >=20 > How often would such functions be useful? Perhaps they fill a gap, but = I'm not sure if it's one that needs filling. array_key_first and = array_key_last can already be accomplished in two or so lines of code = (four if you make a function), and array_key_index can be implemented in = a few lines with a foreach() loop and a counter. array_key_first() and array_key_last() can=E2=80=99t be implemented in = userspace and maintain all three of fast, immutable, and = doesn=E2=80=99t-look-weird. The best you could do for array_key_first() is: function array_key_first($arr) { foreach($arr as $k =3D> $v) return $k; =09 return null; } Which already looks kind of weird. For array_key_last, your best bet is function array_key_last($arr) { $k =3D null;=09 foreach($arr as $k =3D> $v) ; //Rely on the fall-through of $k from the last iteration return $k; } which looks even weirder or=20 function array_key_last($arr) { $keys =3D array_keys($arr); if($cnt =3D count($keys)) return $keys[$cnt - 1]; =09 return null; } Which adds the overhead of array_keys() iterating over the array and = duplicating *all* of the array=E2=80=99s keys just to retrieve one. Any solution that uses reset() + key() or end() + key() mutates the = array, which means duplicating it if you pass it into a function. This = takes a non-trivial time if you have a large array. > array_key_first and array_key_last seem mostly harmless, at least. I'm = not sure the same can be said for array_key_index, since it has O(n) = complexity. I worry that it might end up used by people who think it is = more efficient than iterating through an array, even though it is not. I = would rather we not include this specific function, and avoid = potentially disguising the time complexity of key lookup, especially as = I can't think of a good use-case for it. As for array_key_first and = array_key_last, well, maybe they're useful, I have no strong opinion on = them. They might be handy to get the first and last key of an array = without moving the internal pointer, so who knows, maybe we should add = them. I=E2=80=99ll admit that array_key_index() could be easily abused. If you = need to use it more than a few times on a particular array, unless = you=E2=80=99ve got a huge array and need to keep memory use constrained, = you=E2=80=99re probably better off just calling array_keys() and using = an index into the result. This would need to be included in the = documentation as a use case caveat, though it wouldn=E2=80=99t be = surprising if people ignored the warning and used it incorrectly anyway. The reason array_key_index() is included in the RFC is because it kind = of fell out of the original implementation and since it=E2=80=99s kind = of useful, for a limited set of problems, I kept it in. It=E2=80=99s = really more of a special-case tool with (very) limited general use, but = it is a substantial improvement over the alternatives if you really do = it need. My primary goal with this RFC is array_key_first() and array_key_last(), = so I would not be against having array_key_index() be a separate voting = choice, if that would make people more comfortable. > Thanks. > --=20 > Andrea Faulds > https://ajf.me/ -John