On 30 May 2016 at 03:40, Colin O'Dell <[email protected]> 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: > 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/
