在PHP中转置多维数组

Cal*_*vin 68 php arrays higher-order-functions

你如何在PHP中翻转90度(转置)多维数组?例如:

// 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"
}
Run Code Online (Sandbox Code Playgroud)

你会如何实施flipDiagonally()

编辑:这不是作业.我只是想看看是否有任何SOers比最明显的路线更具创造性的解决方案.但是,由于一些人抱怨这个问题太容易了,那么一个适用于 n 维数组的更通用的解决方案呢?

即如何编写函数以便:

$foo[j][k][...][x][y][z] = $bar[z][k][...][x][y][j]
Run Code Online (Sandbox Code Playgroud)

?(ps.for loops在这种情况下,我不认为12嵌套是最好的解决方案.)

Cod*_*ler 242

function transpose($array) {
    array_unshift($array, null);
    return call_user_func_array('array_map', $array);
}
Run Code Online (Sandbox Code Playgroud)

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

function transpose($array) {
    return array_map(null, ...$array);
}
Run Code Online (Sandbox Code Playgroud)

  • NULL作为array_unshift的参数给出,它为数组的开头添加一个值.因此,第一行插入NULL作为数组的第一个值.下一行调用array_map,其中$ array的所有条目都作为参数.所以它与调用array_map(NULL,$ array [0],$ array [1],$ array [2]等)相同.在array_map文档中有一个细节:"这个函数的一个有趣用途是构造一个数组数组,可以通过使用NULL作为回调函数的名称来轻松执行 (20认同)
  • 如果索引类型为String,则此函数不会保留索引.它返回带有数字索引的转置矩阵.flipDiagonally函数在这种情况下工作正常.为了简单起见,无论如何都要进行投 (13认同)
  • 只有一行时会出现故障,例如转置([[1,2]])预期:[[1],[2]]实际:[1,2] (4认同)
  • 但为什么这样做呢?这个答案对我来说完全不透明 (3认同)
  • 嗯……这对我有用,但是我真的不明白为什么。我看到以$ array作为参数调用了array_map,而第一个参数为null。但是为什么array_map会这样呢?为什么在这里将null作为参数甚至可以? (2认同)
  • 应该是答案中的一些描述. (2认同)

OIS*_*OIS 62

有2个循环.

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

  • 尽管Codler的答案更简洁,但我认为这实际上是更好的方法,因为它正在发生的事情要清楚得多.如果有编码经验而不是php guru的人会查看这两个答案,他们会立即明白这个答案的内容,但是必须阅读文档的精细内容以跟随另一个.+1 (14认同)
  • @donquixote Codler 的解决方案是错误的。糟糕的是。它不支持关联数组,并且在单行/列的简单边缘情况下失败:[[a,b,...,z]]。必须贬低它,以免迷惑人们。 (3认同)

Azi*_*ziz 8

我认为你指的是数组转置(列成为行,行成为列).

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

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;
} 
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,我想知道正确的术语是什么.(没有它,相关信息有点谷歌搜索.) (2认同)