Given an array $arr of the form:
Array (
[0] => Array ([id] => id1, ...)
[1] => Array ([id] => id1, ...)
[2] => Array ([id] => id2, ...)
...
)
Using this foreach loop:
$rowsById = [];
foreach ($arr as $row) {
$rowsById[$row['id']][] = $row;
}
We can transform it to an array of the form (keyed by ids):
Array (
[id1] => Array (
[0] => Array ([id] => id1, ...)
[1] => Array ([id] => id1, ...)
)
[id2] => Array (
[0] => Array ([id] => id2, ...)
)
...
)
Can we do the same thing but without the foreach loop?
(That is, with some iterating function like array_walk and a callback)
From a formal point of view, this solution is a positive answer to your question.
But, if you wanted to speed up the code, or even if you wanted cleaner code without loosing too much somewhere else, here is the surprise: this solution is definitely slower than your
foreachloop (by a factor of 3 on my machine). The reason is almost certainly the function call to the anonymous function, which is absent in the foreach solution. As I already pointed out in another answer here on SO, it’s the function calls that eat up CPU time.This situation could be different if we could just combine simple
array_functions to obtain the same result, but the fact that['id']must be accessed somehow, the overhead of creating intermediate arrays, plus the fact that noarray_function is available for direct assignment to keyed bins, make this an impossible task.For example, this code that I posted before realizing that it was wrong (because it replaces instead of appending to the bins)
runs slower than your
foreachby a factor of 2.5 on my machine.So, at the end, the answer to your question is: “Yes, if we don’t care about processing time”.