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

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

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


当前回答

由于到目前为止还没有人提到函数式递归方法,所以我在这里介绍一下。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% }

其他回答

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

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

我觉得这样可读性更强一点。它使用Array.from,逻辑与使用嵌套循环相同:

Var arr = [ [1,2,3,4], [1,2,3,4], [1,2,3,4] ]; /* * arr[0]。Length = 4 =结果行数 加勒比海盗。长度= 3 =结果cols的个数 * / var result = Array.from({长度:arr[0].)长度},函数(x,行){ 返回Array.from({长度:arr。长度},函数(x, col) { 返回arr (col)(行); }); }); console.log(结果);

如果你在处理长度不等的数组,你需要替换arr[0]。长度与其他东西:

Var arr = [ (1、2), [1,2,3], [1,2,3,4] ]; /* * arr[0]。Length = 4 =结果行数 加勒比海盗。长度= 3 =结果cols的个数 * / var result = Array.from({长度:arr. from)Reduce(函数(max, item){返回item。长度>最大长度?项。长度:max;}, 0)},函数(x,行){ 返回Array.from({长度:arr。长度},函数(x, col) { 返回arr (col)(行); }); }); console.log(结果);

你可以在原地只做一次:

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

只是使用Array.map的另一个变体。使用索引可以转置矩阵,其中M != N:

// Get just the first row to iterate columns first
var t = matrix[0].map(function (col, c) {
    // For each column, iterate all rows
    return matrix.map(function (row, r) { 
        return matrix[r][c]; 
    }); 
});

转置就是先按列映射元素,再按行映射元素。

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

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
}