How can I efficiently split an array into its associative key arrays?

冷暖自知 提交于 2019-12-23 04:39:07

问题


How can I split a single array into it's sub-keys?

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

What is the most efficient way to return an array of foo and bar separately?

I need to get here:

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

I'm hoping there's a clever way to do this using array_map or something similar. Any ideas?

Or do I have to loop through and build each array that way? Something like:

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

回答1:


In a lucky coincidence, I needed to do almost the exact same thing earlier today. You can use array_map() in combination with array_shift():

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

Note that $arr is passed by reference! If you don't do that, then each time it would return the contents of $arr[<index>]['foo']. However, again because of the reference - you won't be able to reuse $arr, so if you need to do that - copy it first.

The downside is that your array keys need to be ordered in the same way as in your example, because array_shift() doesn't actually know what the key is. It will NOT work on the following array:

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

Update:

After reading the comments, it became evident that my solution triggers E_DEPRECATED warnings for call-time-pass-by-reference. Here's the suggested (and accepted as an answer) alternative by @Baba, which takes advantage of the two needed keys being the first and last elements of the second-dimension arrays:

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



回答2:


$n = array();

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



回答3:


array_merge_recursive will combine scalar values with the same key into an array. e.g.:

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

You can use this property to simply apply array_merge_recursive over each array in your array as a separate argument:

call_user_func_array('array_merge_recursive', $arr);

You will get this result:

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

It won't even be confused by keys in different order.

However, every merged value must be scalar! Arrays will be merged instead of added as a sub-array:

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

It does not produce array(array(1, array(2)))!



来源:https://stackoverflow.com/questions/13636015/how-can-i-efficiently-split-an-array-into-its-associative-key-arrays

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!