On Wed, 8 Sept 2021 at 16:10, Andreas Hennings <andr...@dqxtech.net> wrote: > > Thanks for the feedback so far! > > On Wed, 8 Sept 2021 at 10:13, Marco Pivetta <ocram...@gmail.com> wrote: > > > > Heyo, > > > > On Wed, 8 Sep 2021, 02:19 Andreas Hennings, <andr...@dqxtech.net> wrote: > >> > >> Hello internals, > >> > >> The function array_column() would be much more useful if there was an > >> option to preserve the original array keys. > >> I can create an RFC, but I think it is better to first discuss the options. > > > > > > New function, please 🙏 > > I am not opposed. But I am also curious what others think. > What I don't like so much is how the situation with two different > functions will have a "historically grown wtf" smell about it. > But this is perhaps preferable to BC breaks or overly "magic" > parameters or overly crowded signatures. > > If we go for a new function: > A name could be array_column_assoc(). > > array_column_assoc(array $array, string $value_key) > > This would behave the same as array_column($array, $value_key), but > preserve original keys. > Items which are not arrays or which lack the key will be omitted. > A $value_key === NULL would be useless, because this would simply > return the original array. > > The question is, should it do anything beyond the most obvious? > Or should we leave it minimal for now, with the potential for > additional parameters in the future? > > Limitations: > If some items are omitted, it will be awkward to restore the missing > items while preserving the order of the array. > > Possible ideas for additional functionality: > - Replicate a lot of the behavior of array_column(), e.g. with an > optional $index_key parameter. This would be mostly redundant. > - Additional functionality for nested arrays? > - Fallback value for entries that don't have the key? Or perhaps even > a fallback callback like with array_map()? > - Option to capture missing entries e.g. in a by-reference variable? > > A benefit of keeping the limited functionality would be that > programming errors are revealed more easily due to the strict > signature. > > A question is how we would look at this long term: > Do we want both functions to co-exist long-term, or do we want to > deprecate one of them at some point? > If array_column() is going to stay, then array_column_assoc() only > needs to cover the few use cases that are missing. > > -- Andreas
If we want to support nested array structures, it could work like this: NOTE: We actually don't need to squeeze this into array_column_assoc(). We could easily introduce a 3rd function instead, e.g. array_column_recursive(), if/when we want to have this in the future. I am only posting this so that we get an idea about the surrounding design space. $source['a']['b']['x']['c']['y'] = 5; $expected['a']['b']['c'] = 5; assert($expected === array_column_assoc($source, [null, null, 'x', null, 'y'])); Note the first NULL, which only exists to make the system feel more "complete". This could be useful if the array is coming from a function call. The following examples show this: unset($source, $expected); // (reset vars) $source['a']['x']['b'] = 5; $expected['a']['b'] = 5; assert($expected === array_column_assoc($source, [null, 'x'])); assert($expected === array_column_assoc($source, 'x')); unset($source, $expected); // (reset vars) $source['x']['a'] = 5; $expected['a'] = 5; assert($expected === array_column_assoc($source, ['x'])); assert($expected === $source['x'] ?? []); Trailing NULLs do almost nothing, except to ensure that non-arrays are removed from the tree. I would have to think more about the details, but I think it would work like this: unset($source, $expected); // (reset vars) $source['a0']['b'] = 5; $source['a1'] = 5; $expected = $actual; assert($expected === array_column_assoc($source, [])); assert($expected === array_column_assoc($source, [null])); unset($expected['a1']); assert($expected === array_column_assoc($source, [null, null])); unset($expected['a0']); assert($expected === array_column_assoc($source, [null, null])); Another idea could be to "collapse" array levels, using a magic value other than NULL, that does not work as an array key. unset($source, $expected); // (reset vars) $source['a0']['b0'] = 5; $source['a1']['b1'] = 5; $expected['b0'] = 5; $expected['b1'] = 5; assert($expected === array_column_assoc($source, [false])); unset($expected); $expected['a0'] = 5; $expected['a1'] = 5; assert($expected === array_column_assoc($source, [null, false])); -- Andreas -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php