我有一个数组的数组,就像这样:
[
[1,2,3],
[1,2,3],
[1,2,3],
]
我想把它转置得到下面的数组:
[
[1,1,1],
[2,2,2],
[3,3,3],
]
用循环来实现这一点并不难:
function transposeArray(array, arrayLength){
var newArray = [];
for(var i = 0; i < array.length; i++){
newArray.push([]);
};
for(var i = 0; i < array.length; i++){
for(var j = 0; j < arrayLength; j++){
newArray[j].push(array[i][j]);
};
};
return newArray;
}
然而,这看起来很笨重,我觉得应该有更简单的方法来做到这一点。是吗?
这个,不仅是一个超级高效的解,而且是一个很短的解。
算法时间复杂度:O(n log n)
const matrix = [
[1,1,1,1],
[2,2,2,2],
[3,3,3,3],
[4,4,4,4]
];
matrix.every((r, i, a) => (
r.every((_, j) => (
j = a.length-j-1,
[ r[j], a[j][i] ] = [ a[j][i], r[j] ],
i < j-1
)),
i < length-2
));
console.log(matrix);
/*
Prints:
[
[1,2,3,4],
[1,2,3,4],
[1,2,3,4],
[1,2,3,4]
]
*/
上面的例子将只进行6次迭代。
对于更大的矩阵,比如100x100,它将进行4900次迭代,这比这里提供的任何其他解决方案快51%。
原理很简单,你只遍历矩阵对角线的上半部分,因为对角线永远不会改变,下对角线的下半部分和上半部分互换了,所以没有理由也遍历它。这样可以节省大量的运行时间,特别是在大型矩阵中。
这个,不仅是一个超级高效的解,而且是一个很短的解。
算法时间复杂度:O(n log n)
const matrix = [
[1,1,1,1],
[2,2,2,2],
[3,3,3,3],
[4,4,4,4]
];
matrix.every((r, i, a) => (
r.every((_, j) => (
j = a.length-j-1,
[ r[j], a[j][i] ] = [ a[j][i], r[j] ],
i < j-1
)),
i < length-2
));
console.log(matrix);
/*
Prints:
[
[1,2,3,4],
[1,2,3,4],
[1,2,3,4],
[1,2,3,4]
]
*/
上面的例子将只进行6次迭代。
对于更大的矩阵,比如100x100,它将进行4900次迭代,这比这里提供的任何其他解决方案快51%。
原理很简单,你只遍历矩阵对角线的上半部分,因为对角线永远不会改变,下对角线的下半部分和上半部分互换了,所以没有理由也遍历它。这样可以节省大量的运行时间,特别是在大型矩阵中。
如果你可以选择使用Ramda JS和ES6语法,那么这里有另一种方法来做到这一点:
const ' = = > R.map (c = > R.map (r = > [c], a), R.keys ([0]));
console.log(转置([
[1,2,3,4],
[5,6,7,8],
[9,10,11,12]
)));// => [[1,5,9],[2,6,10],[3,7,11],[4,8,12]]]
< script src = " https://cdnjs.cloudflare.com/ajax/libs/ramda/0.22.1/ramda.min.js " > < /脚本>
干净的:
[[0, 1], [2, 3], [4, 5]].reduce((prev, next) => next.map((item, i) =>
(prev[i] || []).concat(next[i])
), []); // [[0, 2, 4], [1, 3, 5]]
以前的解决方案在提供空数组时可能会导致失败。
这是一个函数:
function transpose(array) {
return array.reduce((prev, next) => next.map((item, i) =>
(prev[i] || []).concat(next[i])
), []);
}
console.log(transpose([[0, 1], [2, 3], [4, 5]]));
更新。
它可以用展开运算符写得更好:
const transpose = matrix => matrix.reduce(
($, row) => row.map((_, i) => [...($[i] || []), row[i]]),
[]
)