Transposing a 2D-array in JavaScript

2018-12-31 16:54发布

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?

17条回答
人气声优
2楼-- · 2018-12-31 17:04

ES6 1liners as :

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

so same as Óscar's, but as would you rather rotate it clockwise :

let rotate = a => a[0].map((col, c) => a.map((row, r) => a[r][c]).reverse())
查看更多
不流泪的眼
3楼-- · 2018-12-31 17:05

I found the above answers either hard to read or too verbose, so I write one myself. And I think this is most intuitive way to implement transpose in linear algebra, you don't do value exchange, but just insert each element into the right place in the new matrix:

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
}
查看更多
冷夜・残月
4楼-- · 2018-12-31 17:06

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

transpose = m => m[0].map((x,i) => m.map(x => x[i]))
查看更多
刘海飞了
5楼-- · 2018-12-31 17:07

You could use underscore.js

_.zip.apply(_, [[1,2,3], [1,2,3], [1,2,3]])
查看更多
春风洒进眼中
6楼-- · 2018-12-31 17:08

Just another variation using Array.map. Using indexes allows to transpose matrices where 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.

查看更多
宁负流年不负卿
7楼-- · 2018-12-31 17:09

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;
    }
  }
}
查看更多
登录 后发表回答