使用匿名函数回调来根据值拆分数组

时间:2012-07-07 16:35:05

标签: php arrays callback split

给定格式为$arr的格式:

Array (
    [0] => Array ([id] => id1, ...)
    [1] => Array ([id] => id1, ...)
    [2] => Array ([id] => id2, ...)
    ...
)

使用这个foreach循环:

$rowsById = [];
foreach ($arr as $row) {
    $rowsById[$row['id']][] = $row;
}

我们可以将它转换为表单数组(由id键控):

Array (
    [id1] => Array (
                 [0] => Array ([id] => id1, ...)
                 [1] => Array ([id] => id1, ...)
             )
    [id2] => Array (
                 [0] => Array ([id] => id2, ...)
             )
    ...
)

我们可以做同样的事情,但没有foreach循环吗? (也就是说,使用像array_walk和回调这样的迭代函数)

1 个答案:

答案 0 :(得分:4)

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

从正式的角度来看,这个解决方案对你的问题是一个肯定的答案。

但是,如果你想加速代码,或者即使你想要更清晰的代码而不会在其他地方失去太多,这也是一个惊喜:这个解决方案绝对是比你的foreach循环(我的机器上的 3 因子)。原因几乎可以肯定是对匿名函数的函数调用,这在foreach解决方案中是不存在的。正如我在SO上的另一个answer已经指出的那样,是占用CPU时间的函数调用

如果我们可以只使用简单的array_函数来获得相同的结果,但是必须以某种方式访问​​['id'],创建中间数组的开销以及事实,这种情况可能会有所不同没有array_函数可用于直接分配到键控箱,这使得这是一项不可能完成的任务。

例如,我发现之前发现的这段代码错误(因为它取代而不是附加到垃圾箱)

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

在我的机器上运行速度比foreach慢了 2.5

所以,最后,你的问题的答案是:“是的,如果我们不关心处理时间”。