我有一个数组的数组,就像这样:

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

然而,这看起来很笨重,我觉得应该有更简单的方法来做到这一点。是吗?


当前回答

在这里添加TS版本。

const transpose = <T>(m: Array<Array<T>>): Array<Array<T>> => m[0].map((_, i) => m.map(x => x[i]));

其他回答

不改变给定数组的一行程序。

a[0].map((col, i) => a.map(([...row]) => row[i]))

干净的:

[[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]]), 
    []
)

以下是我在现代浏览器中的实现(不依赖):

transpose = m => m[0].map((x,i) => m.map(x => x[i]))

使用lodash/下划线和es6的最短方式:

_.zip(...matrix)

其中矩阵为:

const matrix = [[1,2,3], [1,2,3], [1,2,3]];

ES6 1liner为:

let invert = a => a[0].map((col, c) => a.map((row, r) => a[r][c]))

所以和Óscar的一样,但你更愿意顺时针旋转它:

let rotate = a => a[0].map((col, c) => a.map((row, r) => a[r][c]).reverse())

let a = [
    [1,1,1]
    , ["_","_","1"]
]
let b = rotate(a);
let c = rotate(b);
let d = rotate(c);
console.log(`a ${a.join("\na ")}`);
console.log(`b ${b.join("\nb ")}`);
console.log(`c ${c.join("\nc ")}`);
console.log(`d ${d.join("\nd ")}`);

收益率

a 1,1,1 
a _,_,1

b _,1
b _,1
b 1,1 

c 1,_,_
c 1,1,1

d 1,1
d 1,_
d 1,_