在PHP中移植multidimensional array

如何在PHP中翻转90度(转置)multidimensional array? 例如:

// 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" } 

你将如何实现flipDiagonally()

编辑:这不是功课。 我只想看看是否有任何SOE比最明显的路线有一个更有创意的解决scheme。 但是由于有些人抱怨这个问题太简单了,那么更一般的解决scheme是如何处理 n维数组呢?

即你将如何编写一个函数,以便:

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

(ps。我不认为在这种情况下12嵌套for loops是最好的解决scheme。)

 function transpose($array) { array_unshift($array, null); return call_user_func_array('array_map', $array); } 

或者如果您使用PHP 5.6或更高版本:

 function transpose($array) { return array_map(null, ...$array); } 

有2个循环。

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

我想你是指数组转置 (列成行,行成列)。

这是一个为你做的function(来源) :

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

转置一个N维数组:

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

真的hackish,可能不是最好的解决scheme,但嘿它的作品。

基本上,它recursion遍历数组,累积当前的指标在一个数组中。
一旦它到达被引用的值,它就会使用索引的“堆栈”并将其反转,并将其放入$ out数组中。 (有没有避免使用$ temp数组的方法?)

我遇到了同样的问题。 这是我想出来的:

 function array_transpose(array $arr) { $keys = array_keys($arr); $sum = array_values(array_map('count', $arr)); $transposed = array(); for ($i = 0; $i < max($sum); $i ++) { $item = array(); foreach ($keys as $key) { $item[$key] = array_key_exists($i, $arr[$key]) ? $arr[$key][$i] : NULL; } $transposed[] = $item; } return $transposed; } 

我需要一个支持关联数组的转置函数:

  $matrix = [ ['one' => 1, 'two' => 2], ['one' => 11, 'two' => 22], ['one' => 111, 'two' => 222], ]; $result = \array_transpose($matrix); $trans = [ 'one' => [1, 11, 111], 'two' => [2, 22, 222], ]; 

而回来的路上:

  $matrix = [ 'one' => [1, 11, 111], 'two' => [2, 22, 222], ]; $result = \array_transpose($matrix); $trans = [ ['one' => 1, 'two' => 2], ['one' => 11, 'two' => 22], ['one' => 111, 'two' => 222], ]; 

array_unshift技巧不工作NOR array_map

所以我编写了一个array_map_join_array函数来处理logging键的关联:

 /** * Similar to array_map() but tries to join values on intern keys. * @param callable $callback takes 2 args, the intern key and the list of associated values keyed by array (extern) keys. * @param array $arrays the list of arrays to map keyed by extern keys NB like call_user_func_array() * @return array */ function array_map_join_array(callable $callback, array $arrays) { $keys = []; // try to list all intern keys array_walk($arrays, function ($array) use (&$keys) { $keys = array_merge($keys, array_keys($array)); }); $keys = array_unique($keys); $res = []; // for each intern key foreach ($keys as $key) { $items = []; // walk through each array array_walk($arrays, function ($array, $arrKey) use ($key, &$items) { if (isset($array[$key])) { // stack/transpose existing value for intern key with the array (extern) key $items[$arrKey] = $array[$key]; } else { // or stack a null value with the array (extern) key $items[$arrKey] = null; } }); // call the callback with intern key and all the associated values keyed with array (extern) keys $res[$key] = call_user_func($callback, $key, $items); } return $res; } 

array_transpose变得明显:

 function array_transpose(array $matrix) { return \array_map_join_array(function ($key, $items) { return $items; }, $matrix); } 

像这样使用

 <?php $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' ) ); echo "<pre>"; $i=0; foreach ($foo as $val) { $i++; $array[$i] = array_column($foo, $i); } print_r($array); ?> 

结果:

 Array ( [1] => Array ( [0] => a1 [1] => b1 [2] => c1 ) [2] => Array ( [0] => a2 [1] => b2 [2] => c2 ) [3] => Array ( [0] => a3 [1] => b3 [2] => c3 ) ) 
 <?php $tableau_init = [ [ "prenom" => "med", "age" => 1 ], [ "prenom" => "hassan", "age" => 2 ], [ "prenom" => "ali", "age" => 3 ] ]; function transpose($tableau){ $out = array(); foreach ($tableau as $key => $value){ foreach ($value as $subKey => $subValue){ $out[$subKey][$key] = $subValue; } } echo json_encode($out); } transpose($tableau_init); 

像这样尝试

在我开始之前,我想再次感谢 @quazardus发布他的转换任何两个联想(或非关联)数组的广义解决scheme!

由于我习惯于尽可能简洁地编写代码,所以我继续将代码“进一步缩小”。 这很可能 不是每个人的口味。 但是,如果有人有兴趣,这里是我的解决scheme:

 function arrayMap($cb, array $arrays) // $cb: optional callback function { $keys = []; array_walk($arrays, function ($array) use (&$keys) { $keys = array_merge($keys, array_keys($array)); }); $keys = array_unique($keys); $res = []; foreach ($keys as $key) { $items = array_map(function ($arr) use ($key) {return isset($arr[$key]) ? $arr[$key] : null; },$arrays); $res[$key] = call_user_func( is_callable($cb) ? $cb : function($k, $itms){return $itms;}, $key, $items); } return $res; } 

现在,类似于PHP标准函数array_map() ,当你调用

 arrayMap(null,$b); 

你会得到所需的转置matrix。