在 JavaScript 中转置二维数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17428587/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 08:17:12  来源:igfitidea点击:

Transposing a 2D-array in JavaScript

javascriptarraysmatrixtranspose

提问by ckersch

I've got an array of arrays, something like:

我有一组数组,例如:

[
    [1,2,3],
    [1,2,3],
    [1,2,3],
]

I would like to transpose it to get the following array:

我想转置它以获得以下数组:

[
    [1,1,1],
    [2,2,2],
    [3,3,3],
]

It's not difficult to programmatically do so using loops:

使用循环以编程方式这样做并不困难:

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

This, however, seems bulky, and I feel like there should be an easier way to do it. Is there?

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

回答by Fawad Ghafoor

array[0].map((_, colIndex) => array.map(row => row[colIndex]));

mapcalls a provided callbackfunction once for each element in an array, in order, and constructs a new array from the results. callbackis invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.

callbackis invoked with three arguments: the value of the element, the index of the element, and the Array object being traversed.[source]

mapcallback按顺序为数组中的每个元素调用一次提供的函数,并根据结果构造一个新数组。callback仅对已分配值的数组索引调用;不会为已删除或从未分配值的索引调用它。

callback使用三个参数调用:元素的值、元素的索引和被遍历的 Array 对象。[来源]

回答by Joe

You could use underscore.js

你可以使用underscore.js

_.zip.apply(_, [[1,2,3], [1,2,3], [1,2,3]])

回答by Mahdi Jadaliha

here is my implementation in modern browser (without dependency):

这是我在现代浏览器中的实现(无依赖):

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

回答by marcel

shortest way with lodash/underscoreand es6:

使用lodash/underscore和的最短方法es6

_.zip(...matrix)

where matrixcould be:

matrix可能在哪里:

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

回答by Yangshun Tay

Many good answers here! I consolidated them into one answer and updated some of the code for a more modern syntax:

这里有很多很好的答案!我将它们合并为一个答案并更新了一些代码以获得更现代的语法:

One-liners inspired by Fawad Ghafoorand óscar Gómez Alca?iz

One-liners 的灵感来自Fawad Ghafooróscar Gómez Alca?iz

function transpose(matrix) {
  return matrix[0].map((col, i) => matrix.map(row => row[i]));
}

function transpose(matrix) {
  return matrix[0].map((col, c) => matrix.map((row, r) => matrix[r][c]));
}

Functional approach style with reduce by Andrew Tatomyr

函数式方法风格 with reduce by Andrew Tatomyr

function transpose(matrix) {
  return matrix.reduce((prev, next) => next.map((item, i) =>
    (prev[i] || []).concat(next[i])
  ), []);
}

Lodash/Underscore by marcel

Lodash /下划线的烫发

function tranpose(matrix) {
  return _.zip(...matrix);
}

// Without spread operator.
function transpose(matrix) {
  return _.zip.apply(_, [[1,2,3], [1,2,3], [1,2,3]])
}

Vanilla approach

香草方法

function transpose(matrix) {
  const rows = matrix.length, cols = matrix[0].length;
  const grid = [];
  for (let j = 0; j < cols; j++) {
    grid[j] = Array(rows);
  }
  for (let i = 0; i < rows; i++) {
    for (let j = 0; j < cols; j++) {
      grid[j][i] = matrix[i][j];
    }
  }
  return grid;
}

Vanilla in-place ES6 approach inspired by Emanuel Saringan

Emanuel Saringan启发的 Vanilla 就地 ES6 方法

function transpose(matrix) {
  for (var i = 0; i < matrix.length; i++) {
    for (var j = 0; j < i; j++) {
      const temp = matrix[i][j];
      matrix[i][j] = matrix[j][i];
      matrix[j][i] = temp;
    }
  }
}

// Using destructing
function transpose(matrix) {
  for (var i = 0; i < matrix.length; i++) {
    for (var j = 0; j < i; j++) {
      [matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]];
    }
  }
}

回答by Andrew Tatomyr

Neat and pure:

干净利落:

[[0, 1], [2, 3], [4, 5]].reduce((prev, next) => next.map((item, i) =>
    (prev[i] || []).concat(next[i])
), []); // [[0, 2, 4], [1, 3, 5]]

Previous solutions may lead to failure in case an empty array is provided.

如果提供空数组,以前的解决方案可能会导致失败。

Here it is as a function:

这是一个函数:

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]]));

Update.It can be written even better with spread operator:

更新。使用扩展运算符可以写得更好:

const transpose = matrix => matrix.reduce(
    ($, row) => row.map((_, i) => [...($[i] || []), row[i]]), 
    []
)

回答by Emanuel Saringan

You can do it in in-place by doing only one pass:

您只需执行一次即可就地完成:

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

回答by óscar Gómez Alca?iz

Just another variation using Array.map. Using indexes allows to transpose matrices where M != N:

只是使用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]; 
    }); 
});

All there is to transposing is mapping the elements column-first, and then by row.

转置所要做的就是先按列映射元素,然后按行映射元素。

回答by Kevin Le - Khnle

If you have an option of using Ramda JS and ES6 syntax, then here's another way to do it:

如果您可以选择使用 Ramda JS 和 ES6 语法,那么这是另一种方法:

const transpose = a => R.map(c => R.map(r => r[c], a), R.keys(a[0]));

console.log(transpose([
  [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"></script>

回答by Nina Scholz

Another approach by iterating the array from outside to inside and reduce the matrix by mapping inner values.

另一种方法是从外到内迭代数组,并通过映射内部值来减少矩阵。

const
    transpose = array => array.reduce((r, a) => a.map((v, i) => [...(r[i] || []), v]), []),
    matrix = [[1, 2, 3], [1, 2, 3], [1, 2, 3]];

console.log(transpose(matrix));