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

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

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


当前回答

干净的:

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

其他回答

你可以在原地只做一次:

function transpose(arr,arrLen) {
  for (var i = 0; i < arrLen; i++) {
    for (var j = 0; j <i; j++) {
      //swap element[i,j] and element[j,i]
      var temp = arr[i][j];
      arr[i][j] = arr[j][i];
      arr[j][i] = temp;
    }
  }
}

我发现上面的答案要么很难读懂,要么太啰嗦,所以我自己写了一个。我认为这是在线性代数中实现转置的最直观的方法,你不做值交换,而只是把每个元素插入到新矩阵的正确位置:

function transpose(matrix) {
  const rows = matrix.length
  const cols = matrix[0].length

  let grid = []
  for (let col = 0; col < cols; col++) {
    grid[col] = []
  }
  for (let row = 0; row < rows; row++) {
    for (let col = 0; col < cols; col++) {
      grid[col][row] = matrix[row][col]
    }
  }
  return grid
}

由于到目前为止还没有人提到函数式递归方法,所以我在这里介绍一下。Haskell's Data.List.transpose的改编。

Var转置= as => as。长度呢?[0]。长度呢?(如。Reduce ((rs, a) => a.length ?(rs.push(a[0]), rs): rs, [] ),…转置(如。Map (a => a.slice(1)))]: 置(as.slice (1)): [], MTX = [ [1], (1、2), [1,2,3] ]; console.log(转置(mtx)) .as-console-wrapper { Max-height: 100% }

编辑:这个答案不会转置矩阵,而是旋转它。我一开始就没有仔细阅读问题:D

顺时针和逆时针旋转:

    function rotateCounterClockwise(a){
        var n=a.length;
        for (var i=0; i<n/2; i++) {
            for (var j=i; j<n-i-1; j++) {
                var tmp=a[i][j];
                a[i][j]=a[j][n-i-1];
                a[j][n-i-1]=a[n-i-1][n-j-1];
                a[n-i-1][n-j-1]=a[n-j-1][i];
                a[n-j-1][i]=tmp;
            }
        }
        return a;
    }

    function rotateClockwise(a) {
        var n=a.length;
        for (var i=0; i<n/2; i++) {
            for (var j=i; j<n-i-1; j++) {
                var tmp=a[i][j];
                a[i][j]=a[n-j-1][i];
                a[n-j-1][i]=a[n-i-1][n-j-1];
                a[n-i-1][n-j-1]=a[j][n-i-1];
                a[j][n-i-1]=tmp;
            }
        }
        return a;
    }

Const转置=数组=>数组[0]。Map ((r, i) =>数组。Map (c => c[i])); Console.log(转置([[2,3,4],[5,6,7]]));