Re: Re: [RFC] array_key_(first|last|index) functions proposal

From: Date: Mon, 04 Jan 2016 18:34:10 +0000
Subject: Re: Re: [RFC] array_key_(first|last|index) functions proposal
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-89997@lists.php.net to get a copy of this message
Hi Andrea, > On Jan 4, 2016, at 12:05, Andrea Faulds <ajf@ajf.me> wrote: > > Hi John, > > John Bafford wrote: >> Happy New Year, everyone! >> >> I’d 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’s property that arrays are ordered maps. >> >> RFC: https://wiki.php.net/rfc/array_key_first_last_index >> PR: https://github.com/php/php-src/pull/347 > > 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’t be implemented in userspace and maintain all three of fast, immutable, and doesn’t-look-weird. The best you could do for array_key_first() is: function array_key_first($arr) { foreach($arr as $k => $v) return $k; return null; } Which already looks kind of weird. For array_key_last, your best bet is function array_key_last($arr) { $k = null; foreach($arr as $k => $v) ; //Rely on the fall-through of $k from the last iteration return $k; } which looks even weirder or function array_key_last($arr) { $keys = array_keys($arr); if($cnt = count($keys)) return $keys[$cnt - 1]; return null; } Which adds the overhead of array_keys() iterating over the array and duplicating *all* of the array’s 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’ll 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’ve got a huge array and need to keep memory use constrained, you’re 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’t 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’s kind of useful, for a limited set of problems, I kept it in. It’s 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. > -- > Andrea Faulds > https://ajf.me/ -John

« previous php.internals (#89997) next »