首先,你不想要什么(这是你想要的解决方案的一半)......
“翻转行和列”的术语是“转置”。
自从 splat 运算符被添加到语言中以来,PHP 就为这个动作提供了一种时尚的原生技术。
要记住的警告是:
- 所有键都必须是数字。splat/spread 运算符将阻塞非数字键。
- 矩阵必须是完整的。如果有任何差距,您可能无法得到您想要的结果。
代码:(演示)
$matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12],
];
var_export(
array_map(null, ...$matrix)
);
输出:
[
[1, 4, 7, 10],
[2, 5, 8, 11],
[3, 6, 9, 12],
];
现在,为了你想要的!
这是一个功能风格的片段,它结合了 php 的转置技术,同时确保输出与输入具有相同的列数。
代码:(演示)
var_export(
array_map(
null,
...array_chunk(
array_merge(...$matrix),
count($matrix)
)
)
);
输出:
[
[1, 5, 9],
[2, 6, 10],
[3, 7, 11],
[4, 8, 12],
];
这种方法将输入展平,然后将其分成长度等于原始行数的行,然后转置该结果。
后期编辑:作为纯粹的学术追求,我想看看不使用任何条件且不维护多个“计数器”的纯数学技术会是什么样子。
事实证明,因为 php 数组会将浮点键截断为整数,所以这可以在单个循环中完成。
// assuming the earlier mentioned 3x4 matrix:
i old pos new pos i%rows i/rows i/col i%col
0 : [0][0] => [0][0] 0 0 0 0
1 : [1][0] => [0][1] 1 0.25 0.3 1
2 : [2][0] => [0][2] 2 0.5 0.6 2
3 : [3][0] => [1][0] 3 0.75 1 0
4 : [0][1] => [1][1] 0 1 1.3 1
5 : [1][1] => [1][2] 1 1.25 1.6 2
6 : [2][1] => [2][0] 2 1.5 2 0
7 : [3][1] => [2][1] 3 1.75 2.3 1
8 : [0][2] => [2][2] 0 2 2.6 2
9 : [1][2] => [3][0] 1 2.25 3 0
10 : [2][2] => [3][1] 2 2.5 3.3 1
11 : [3][2] => [3][2] 3 2.75 3.6 2
代码:(演示)
$rows = count($matrix);
$cols = count(current($matrix));
$cells = $rows * $cols;
$result = $matrix; // used to preserve original key orders
for ($i = 0; $i < $cells; ++$i) {
$result[$i % $rows][$i / $rows] = $matrix[$i / $cols][$i % $cols];
}
var_export($result);