1

Having an associative array like

$myarray = array (
  'user' => array (
      2 => 'john',
      5 => 'done',
      21 => 'foo'
  ),
  'city' => array (
      2 => 'london',
      5 => 'buenos aires',
      21 => 'paris',
  ),
  'age' => array (
      2 => 24,
      5 => 38,
      21 => 16
  )
  ...
);

EDITED
Assuming I don't know how many keys this array has, nor the keys themselves (they could be whatever) The above is just an example

Is there any elegant way (using built-in functions and not loops) to convert it into

$result = array(
    array(
        'user',
        'city',
        'age'
        ...
    ),
    array(
        'john',
        'london',
        24
        ...
    ),
    array(
        'done',
        'buenos aires',
        38
        ...
    ),
    array(
        'foo',
        'paris',
        16
        ...
    )
);




As a side question: how to obtain this too (in a similar elegant way)

$result = array(
    array(
        'row',
        'user',
        'city',
        'age'
        ...
    ),
    array(
        2,
        'john',
        'london',
        24
        ...
    ),
    array(
        5,
        'done',
        'buenos aires',
        38
        ...
    ),
    array(
        21,
        'foo',
        'paris',
        16
        ...
    )
);
Luca Borrione
  • 16,324
  • 8
  • 52
  • 66

2 Answers2

3

Note that both of these operations are basically the transpose of your original array.

All of this is strongly adapted from this answer (consider upvoting it!).

helper

First we need a helper function, which keeps the row headers as the keys in the associative array:

function flipArrayKeys($arr) {
    $out = array('row' => array_keys($arr));
    foreach ($arr as $key => $subarr) {
        foreach ($subarr as $subkey => $subvalue) {
            $out[$subkey][] = $subvalue;
        }
    }
    return $out;
}

flipArrayKeys($myarray) gives:

array (
  'row' => 
  array (
    0 => 'user',
    1 => 'city',
    2 => 'age',
  ),
  2 => 
  array (
    0 => 'john',
    1 => 'london',
    2 => 24,
  ),
  5 => 
  array (
    0 => 'done',
    1 => 'buenos aires',
    2 => 38,
  ),
  21 => 
  array (
    0 => 'foo',
    1 => 'paris',
    2 => 16,
  ),
)

part 1

$result = array_values(flipArrayKeys($myarray));

and now result looks like:

array (
  0 => 
  array (
    0 => 'user',
    1 => 'city',
    2 => 'age',
  ),
  1 => 
  array (
    0 => 'john',
    1 => 'london',
    2 => 24,
  ),
  2 => 
  array (
    0 => 'done',
    1 => 'buenos aires',
    2 => 38,
  ),
  3 => 
  array (
    0 => 'foo',
    1 => 'paris',
    2 => 16,
  ),
)

This part can also be done using transpose from this answer:

$result = transpose($myarray);
array_unshift($result, array_keys($myarray));

part 2

function flipArrayWithHeadings($arr) {
    $out = flipArrayKeys($arr);

    foreach (array_keys($out) as $key) {
        array_unshift($out[$key],$key);
    }
    return array_values($out);
}

So flipArrayWithHeadings($myarray) looks like:

array (
  0 => 
  array (
    0 => 'row',
    1 => 'user',
    2 => 'city',
    3 => 'age',
  ),
  1 => 
  array (
    0 => 2,
    1 => 'john',
    2 => 'london',
    3 => 24,
  ),
  2 => 
  array (
    0 => 5,
    1 => 'done',
    2 => 'buenos aires',
    3 => 38,
  ),
  3 => 
  array (
    0 => 21,
    1 => 'foo',
    2 => 'paris',
    3 => 16,
  ),
)
Community
  • 1
  • 1
huon
  • 94,605
  • 21
  • 231
  • 225
  • I need a resulting array mixed differently, please look better: for example the last one won't be array(24, 38, 16), but array('foo', 'paris', 16) .. they are completely remapped – Luca Borrione May 08 '12 at 14:05
  • Sorry, I read the question incorrectly; should be fixed now! :) (unfortunately not particularly elegant.) – huon May 08 '12 at 14:25
3

Use the array_values function as:

$result = array(array_values($myarray['user']), 
          array_values($myarray['city']), 
          array_values($myarray['age']));

For the 2nd part of the question you can do:

$result2 = array_keys($myarray);

foreach(array_keys($myarray['user']) as $k) {
  $result2[] = array($k, $myarray['user'][$k], $myarray['city'][$k], $myarray['age'][$k]);
}
codaddict
  • 445,704
  • 82
  • 492
  • 529