2

给定一个形式的数组$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 和回调)

4

1 回答 1

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

从正式的角度来看,此解决方案是对您问题的肯定回答。

但是,如果您想加快代码速度,或者即使您想要更简洁的代码而又不会在其他地方丢失太多,这里有一个惊喜:这个解决方案肯定比您的循环慢(在我的机器上是3倍)原因几乎可以肯定是对匿名函数的函数调用,而这在 foreach 解决方案中是不存在的。正如我在 SO的另一个答案中已经指出的那样,是函数调用占用了 CPU 时间foreach

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

例如,我在意识到它错误之前发布的这段代码(因为它替换而不是附加到垃圾箱)

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

在我的机器上运行速度比你的慢2.5foreach倍。

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

于 2012-07-07T16:44:42.600 回答