Search code examples
phparraysarray-map

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


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'];
}

Solution

  • 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);