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

Php 使用匿名函数回调根据值拆分数组,php,arrays,callback,split,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;

给定以下形式的数组
$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键入):

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

从正式的角度来看,这个解决方案是对您的问题的积极回答

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

如果我们可以将简单的
数组
函数组合在一起以获得相同的结果,这种情况可能会有所不同,但是必须以某种方式访问
['id']
,创建中间数组的开销,加上没有
数组
函数可直接分配给键控存储箱,让这成为一项不可能的任务

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

在我的机器上,运行速度比您的
foreach
慢一倍2.5

因此,在最后,你的问题的答案是:“是的,如果我们不关心处理时间的话”

从正式的角度来看,这个解决方案是对您的问题的积极回答

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

如果我们可以将简单的
数组
函数组合在一起以获得相同的结果,这种情况可能会有所不同,但是必须以某种方式访问
['id']
,创建中间数组的开销,加上没有
数组
函数可直接分配给键控存储箱,让这成为一项不可能的任务

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

在我的机器上,运行速度比您的
foreach
慢一倍2.5


因此,在最后,您的问题的答案是:“是的,如果我们不关心处理时间的话。”

这不起作用,结果数组中的每个键都有一个值,而不是一个值数组。我假设这个Q的主旨是将操作码执行提升到更高效的C(++)编码库调用中。此解决方案的问题是,每个数组元素仍执行相同数量的PHP操作码,因此我怀疑运行时是否会有实质性的更改。@TerryE很遗憾,您是对的。此外,我将要更正
array\u reduce
array\u walk
,以避免在添加element@JRL:好的,现在我的答案是稳定的。如果有人能想出更好的办法,我会+1,promised@JRL当前位置显然,我的回答不够稳定。除了前两行之外,我已经完全重写了它…这不起作用,结果数组中每个键都有一个值,而不是一个值数组。我假设这个Q的主旨是将操作码执行提升到更高效的C(++)编码库调用中。此解决方案的问题是,每个数组元素仍执行相同数量的PHP操作码,因此我怀疑运行时是否会有实质性的更改。@TerryE很遗憾,您是对的。此外,我将要更正
array\u reduce
array\u walk
,以避免在添加element@JRL:好的,现在我的答案是稳定的。如果有人能想出更好的办法,我会+1,promised@JRL当前位置显然,我的回答不够稳定。除了前两行,我已经完全重写了一遍。。。
Array (
    [id1] => Array (
                 [0] => Array ([id] => id1, ...)
                 [1] => Array ([id] => id1, ...)
             )
    [id2] => Array (
                 [0] => Array ([id] => id2, ...)
             )
    ...
)
$map = array();
array_walk($arr, function($row, $i) use(&$map) { $map[$row['id']][] = $row; });
$map = array_combine(array_map(function($a) { return $a['id']; }, $arr), $arr);