Re: [RFC Discussion] array_change_keys()

From: Date: Mon, 30 May 2016 20:30:14 +0000
Subject: Re: [RFC Discussion] array_change_keys()
References: 1 2 3  Groups: php.internals 
Request: Send a blank email to internals+get-93641@lists.php.net to get a copy of this message
On 30 May 2016 at 03:40, Colin O'Dell <colinodell@gmail.com> wrote: > Marco, > > >> 1. could you also provide the code for the benchmarks? I'd gladly >> measure them with an accurate tool >> > > Yeah that would be great! Here's the benchmark I was using: > åûðJ‚%î'ì8ñ > Ý tžhttps://gist.github.com/colinodell/872c1f0c92351af687347c0c8be4f253 > Ported to https://github.com/Ocramius/array_change_keys-benchmark, thanks! > 2. do we really need another array function that is basically an >> array_combine(array_map($someFunc, array_keys($arr)), >> $arr)? >> > > While array_combine() technically works, the callback does not have access > to both the key AND value. Anyone needing access to both must currently > resort to using a foreach loop (unless there's some other clever > combination of functions that I'm missing). > > We already have array_change_key_case(). IMO that function is way too > specific and not applicable in 99% of situations where you need to re-key > an array. This is why I'm proposing a general purpose function custom > tailored to rekeying an array. > > I'll touch on some other advantages further down this message. > From what I can see from the benchmarks, a userland implementation of this is not really very different from a core implementation of it, as the only removed overhead has pretty much an O(1), while overhead is introduced by forcing the key change via a callable. > > 3. and... do we really want another function that accepts arrays and not >> generic Traversable (and therefore also generators)? >> > > Do the other array functions support this? If not then I'd argue that > adding Traversable support to array functions should be part of a broader > RFC which adds this support to all applicable functions at once. > No, but I really don't care about the other functions. If something doesn't support a Traversable in today's jungle of Generators and asynchronous processing. > In the mean time, you could certainly use iterator_to_array with this > proposed function: > > $b = array_change_keys(iterator_to_array($a), $callback); > This is not usable: Iterators may be infinite, you can't know. Also, this operation may cause a lot of blocking I/O, while instead we want to operate only on the first N elements of an iterator. Doing this with array_combine() would require an intermediate variable to > prevent a "Fatal error: Uncaught Exception: Cannot traverse an already > closed generator": > > $b = iterator_to_array($a); > $a = array_combine(array_map($callback, array_keys($b)), $b); > Yes, this is not workable, as I mention above. Unpacking an iterator into an array defeats the advantages of having an iterator. > Even if all array functions did support generators you'd still need this > intermediate variable to prevent the double traversal - array_change_keys() > would not have this problem. > Yeah, I know what you mean here, but I don't think that the solution is to add more array_* stuff that is as legacy as the previous. > 4. what is the real-world benefit over just >> array_combine(array_map($someFunc, array_keys($arr)), >> $arr), except for >> the two additional function calls here? >> > > There are several IMO: > > 1. Callback has access to both the original key AND the original value. > The array_combine() approach can only access one or the other. > A loop has that too, and a userland looping implementation is still faster > 2. Better performance (hoping you can confirm this). > Sadly not :-( > 3. Purpose of the array_*() function is immediately obvious. > Disagree, as mentioned in few edge cases in other responses (something about numerical keys, IIRC: can't find the actual reply) > 4. No need for intermediate variable when working with iterators means > function composition is possible. > Function composition can be applied also with a userland implementation. My main issue with this is that it doesn't need to exist in *core*. Doesn't mean that it can't exist in userland ;-) Cheers, Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/

« previous php.internals (#93641) next »