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

a 夏天 提交于 2019-12-08 05:06:48

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);
$n = array();

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

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)))!

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