2012-07-07 148 views
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; 
} 

我们可以把它转换为数组的形式(由IDS键控):

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

灿我们做同样的事情,但没有foreach循环? (也就是说,像array_walk和回调一些迭代函数)

回答

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

从形式上看,这种解决方案是一个积极的回答你的问题。

,如果你想加快代码,甚至如果你想更清晰的代码不会丢失太多别的地方,这里是大吃一惊:这个解决方案绝对是比你foreach循环较慢(由在我的机器上的的因子)。原因几乎可以肯定是对匿名函数的函数调用,这在foreach解决方案中是不存在的。正如我在另一个answer上指出的那样,这是函数调用消耗CPU时间

这种情况可能会有所不同。如果我们能够结合简单array_函数来获得相同的结果,但事实证明,['id']必须以某种方式访问​​,创建中间阵列的开销,再加上事实上没有array_功能可用于直接分配到键控箱,使这是一个不可能的任务。

例如,这个代码,我意识到它是错误(因为它取代的,而不是追加到垃圾箱)由2.5因素

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

运行比你foreach慢之前发布在我的机器上。

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

+0

这不起作用,结果数组对每个键都有一个值,而不是一个值数组。 – JRL 2012-07-07 17:04:05

+0

@JRL你是对的,我正要修复它 – 2012-07-07 17:10:58

+0

@JRL固定的,但必须有更好的方法... – 2012-07-07 17:14:44