如何有效地将数组拆分为关联键数组?

时间:2012-11-29 22:34:25

标签: php arrays array-map

如何将单个数组拆分为子键?

$arr = array(
             0 => array(
                        'foo' => '1',
                        'bar' => 'A'
                       ),
             1 => array(
                        'foo' => '2',
                        'bar' => 'B'
                       ),
             2 => array(
                        'foo' => '3',
                        'bar' => 'C'
                       )
            );

分别返回foo和bar数组的最有效方法是什么?

我需要到达这里:

$foo = array('1','2','3');
$bar = array('A','B','C');

我希望有一种聪明的方法可以使用array_map或类似的东西来做到这一点。有什么想法吗?

或者我必须循环并以这种方式构建每个数组?类似的东西:

foreach ($arr as $v) {
    $foo[] = $v['foo'];
    $bar[] = $v['bar'];
}

3 个答案:

答案 0 :(得分:1)

幸运的是,我今天早些时候需要完成同样的事情。您可以将array_map()array_shift()结合使用:

$foo = array_map('array_shift', &$arr);
$bar = array_map('array_shift', &$arr);

请注意,$arr是通过引用传递的!如果你不这样做,那么每次它都会返回$arr[<index>]['foo']的内容。但是,再次因为引用 - 您将无法重用$arr,因此如果您需要这样做 - 请先复制它。

缺点是您的数组键需要以与示例相同的方式进行排序,因为array_shift()实际上并不知道键是什么。它不适用于以下数组:

$arr = array(
    0 => array(
        'foo' => '1',
        'bar' => 'A'
    ),
    1 => array(
        'bar' => 'B',
        'foo' => '2'
    ),
    2 => array(
        'foo' => '3',
        'bar' => 'C'
    )
);

<强>更新

阅读完评论后,很明显我的解决方案触发了E_DEPRECATED警告,用于呼叫时间传递参考。这是@Baba的建议(并被接受为答案)替代方案,它利用了两个所需的键作为第二维数组的第一个和最后一个元素:

$foo = array_map('array_shift', $arr);
$bar = array_map('array_pop', $arr);

答案 1 :(得分:0)

$n = array();

foreach($arr as $key=>$val) {
    foreach($val as $k=>$v) {
        $n[$k][] = $v;
    }
}

答案 2 :(得分:0)

array_merge_recursive会将标量值与相同的键组合成一个数组。 e.g:

array_merge_recursive(array('a',1), array('b',2)) === array(array('a','b'),array(1,2));

您可以使用此属性将array_merge_recursive简单地应用于数组中的每个数组作为单独的参数:

call_user_func_array('array_merge_recursive', $arr);

你会得到这个结果:

array (
  'foo' => 
  array (
    0 => '1',
    1 => '2',
    2 => '3',
  ),
  'bar' => 
  array (
    0 => 'A',
    1 => 'B',
    2 => 'C',
  ),
)

它甚至不会被不同顺序的键混淆。

但是,每个合并的值必须是标量!数组将合并而不是作为子数组添加:

array_merge_recursive(array(1), array(array(2)) === array(array(1,2))

生成array(array(1, array(2)))