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

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

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


当前回答

如果使用RamdaJS是一个选项,这可以在一行中实现:

其他回答

你可以在原地只做一次:

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.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 invertArray(array,arrayWidth,arrayHeight) {
  var newArray = [];
  for (x=0;x<arrayWidth;x++) {
    newArray[x] = [];
    for (y=0;y<arrayHeight;y++) {
        newArray[x][y] = array[y][x];
    }
  }
  return newArray;
}

您可以通过使用以下方法在不使用循环的情况下实现这一点。

数组 Array.prototype.map Array.prototype.reduce Array.prototype.join String.prototype.split

它看起来非常优雅,它不需要任何依赖,如jQuery的Underscore.js。

function transpose(matrix) {  
    return zeroFill(getMatrixWidth(matrix)).map(function(r, i) {
        return zeroFill(matrix.length).map(function(c, j) {
            return matrix[j][i];
        });
    });
}

function getMatrixWidth(matrix) {
    return matrix.reduce(function (result, row) {
        return Math.max(result, row.length);
    }, 0);
}

function zeroFill(n) {
    return new Array(n+1).join('0').split('').map(Number);
}

缩小

function transpose(m){return zeroFill(m.reduce(function(m,r){return Math.max(m,r.length)},0)).map(function(r,i){return zeroFill(m.length).map(function(c,j){return m[j][i]})})}function zeroFill(n){return new Array(n+1).join("0").split("").map(Number)}

这是我做的一个演示。注意没有循环:-)

// Create a 5 row, by 9 column matrix. var m = CoordinateMatrix(5, 9); // Make the matrix an irregular shape. m[2] = m[2].slice(0, 5); m[4].pop(); // Transpose and print the matrix. println(formatMatrix(transpose(m))); function Matrix(rows, cols, defaultVal) { return AbstractMatrix(rows, cols, function(r, i) { return arrayFill(cols, defaultVal); }); } function ZeroMatrix(rows, cols) { return AbstractMatrix(rows, cols, function(r, i) { return zeroFill(cols); }); } function CoordinateMatrix(rows, cols) { return AbstractMatrix(rows, cols, function(r, i) { return zeroFill(cols).map(function(c, j) { return [i, j]; }); }); } function AbstractMatrix(rows, cols, rowFn) { return zeroFill(rows).map(function(r, i) { return rowFn(r, i); }); } /** Matrix functions. */ function formatMatrix(matrix) { return matrix.reduce(function (result, row) { return result + row.join('\t') + '\n'; }, ''); } function copy(matrix) { return zeroFill(matrix.length).map(function(r, i) { return zeroFill(getMatrixWidth(matrix)).map(function(c, j) { return matrix[i][j]; }); }); } function transpose(matrix) { return zeroFill(getMatrixWidth(matrix)).map(function(r, i) { return zeroFill(matrix.length).map(function(c, j) { return matrix[j][i]; }); }); } function getMatrixWidth(matrix) { return matrix.reduce(function (result, row) { return Math.max(result, row.length); }, 0); } /** Array fill functions. */ function zeroFill(n) { return new Array(n+1).join('0').split('').map(Number); } function arrayFill(n, defaultValue) { return zeroFill(n).map(function(value) { return defaultValue || value; }); } /** Print functions. */ function print(str) { str = Array.isArray(str) ? str.join(' ') : str; return document.getElementById('out').innerHTML += str || ''; } function println(str) { print.call(null, [].slice.call(arguments, 0).concat(['<br />'])); } #out { white-space: pre; } <div id="out"></div>

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

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
}