Use of an anonymous function callback to split array based on value

arrays, callback, php, split

Solution

$map = array();
array_walk($arr, function($row, $i) use(&$map) { $map[$row['id']][] = $row; });

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 `foreach` loop (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 no `array_` 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)

$map = array_combine(array_map(function($a) { return $a['id']; }, $arr), $arr);

runs slower than your `foreach` by 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".

Problem

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)

Original source

Related problems