tags:

views:

1733

answers:

4

How would you flip 90 degrees (transpose) a multidimensional array in PHP? For example:

// Start with this array
$foo = array(
    'a' => array(
       1 => 'a1',
       2 => 'a2',
       3 => 'a3' 
    ),
    'b' => array(
       1 => 'b1',
       2 => 'b2',
       3 => 'b3' 
    ),
    'c' => array(
       1 => 'c1',
       2 => 'c2',
       3 => 'c3' 
    )
);

$bar = flipDiagonally($foo); // Mystery function
var_dump($bar[2]);

// Desired output:
array(3) {
  ["a"]=>
  string(2) "a2"
  ["b"]=>
  string(2) "b2"
  ["c"]=>
  string(2) "c2"
}

How would you implement flipDiagonally()?

Edit: this is not homework. I just want to see if any SOers have a more creative solution than the most obvious route. But since a few people have complained about this problem being too easy, what about a more general solution that works with an nth dimension array?

i.e. How would you write a function so that:

$foo[j][k][...][x][y][z] = $bar[z][k][...][x][y][j]

?(ps. I don't think 12 nested for loops is the best solution in this case.)

+5  A: 

With 2 loops.

function flipDiagonally($arr) {
    $out = array();
    foreach ($arr as $key => $subarr) {
     foreach ($subarr as $subkey => $subvalue) {
      $out[$subkey][$key] = $subvalue;
     }
    }
    return $out;
}
OIS
+1  A: 

I think you're referring to the array transpose (columns become rows, rows become columns).

Here is a function that does it for you (source):

function array_transpose($array, $selectKey = false) {
    if (!is_array($array)) return false;
    $return = array();
    foreach($array as $key => $value) {
        if (!is_array($value)) return $array;
        if ($selectKey) {
            if (isset($value[$selectKey])) $return[] = $value[$selectKey];
        } else {
            foreach ($value as $key2 => $value2) {
                $return[$key2][$key] = $value2;
            }
        }
    }
    return $return;
}
Aziz
Thank you, I was wondering what the correct terminology was. (It's a bit hard googling for relevant info without it.)
Calvin
A: 

Transposing an N-dimensional array:

function transpose($array, &$out, $indices = array())
{
    if (is_array($array))
    {
     foreach ($array as $key => $val)
     {
      //push onto the stack of indices
      $temp = $indices;
      $temp[] = $key;
      transpose($val, $out, $temp);
     }
    }
    else
    {
     //go through the stack in reverse - make the new array
     $ref = &$out;
     foreach (array_reverse($indices) as $idx)
      $ref = &$ref[$idx];
     $ref = $array;
    }
}

$foo[1][2][3][3][3] = 'a';
$foo[4][5][6][5][5] = 'b';

$out = array();
transpose($foo, $out);

echo $out[3][3][3][2][1] . ' ' . $out[5][5][6][5][4];

Really hackish, and probably not the best solution, but hey it works.

Basically it traverses the array recursively, accumulating the current indicies in an array.
Once it gets to the referenced value, it takes the "stack" of indices and reverses it, putting it into the $out array. (Is there a way of avoiding use of the $temp array?)

v3
+1  A: 
function transpose($array) {
    array_unshift($array, null);
    return call_user_func_array('array_map', $array);
}
Codler