I have been going through online study on a resource I quite liked till this very moment.
The problem is they want my perfectly working array_reduce
function is written "in immutable style". Which means that nothing should mutate inside, even accumulator. Which seems to me like making no sense.
So, here is a piece of code I use in that study project they do not want to accept, function for flattening an array:
function flatten(array $tree)
{
$result = array_reduce($tree, function ($acc, $item) {
$newValue = is_array($item) ? flatten($item) : $item;
if (!is_array($newValue)) {
$acc[] = $newValue;
} else {
$acc = array_merge($acc, $newValue);
}
return $acc;
}, []);
return $result;
}
It works perfectly but this resourse (not free, BTW) does not accept it with notices "Should not use of mutating operators" to the lines where I change $acc.
So I ask them WTF and they answer me: do not change input argument and make a new acc instead and return this new acc from the callback. So I rewrite like this:
function flatten(array $tree)
{
$result = array_reduce($tree, function ($acc, $item) {
$accNew = $acc;
$newValue = is_array($item) ? flatten($item) : $item;
if (!is_array($newValue)) {
$accNew[] = $newValue;
} else {
$accNew = array_merge($acc, $newValue);
}
return $accNew;
}, []);
return $result;
}
But this doesn't help, the same "Should not use of mutating operators" notices for the lines where now $accNew is being changed.
What the hell? I'm completely confused. Does this even make sense? Is this an appropriate demand? 'Cause I googled on it and it seems there are pretty much no people on Internet who were interested in using array_reduce
"in immutable style"...
I'm not 100% certain how this code gets used, but I think you might even be able to skip writing to the accumulator or a copy of it completely, and just return
instead:
function flatten(array $tree): array
{
return array_reduce(
$tree,
static function ($acc, $item) {
$newValue = is_array($item) ? flatten($item) : $item;
return array_merge($acc, is_array($newValue) ? $newValue : [$newValue]);
},
[]
);
}
Edit: My previous answer didn’t account for previous items in the accumulator, this does.