Transposing a 2D-array in JavaScript

后端 未结 23 2899
难免孤独
难免孤独 2020-11-22 01:40

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

相关标签:
23条回答
  • 2020-11-22 02:11

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

    transpose = m => m[0].map((x,i) => m.map(x => x[i]))
    
    0 讨论(0)
  • 2020-11-22 02:11

    I didn't find an answer that satisfied me, so I wrote one myself, I think it is easy to understand and implement and suitable for all situations.

        transposeArray: function (mat) {
            let newMat = [];
            for (let j = 0; j < mat[0].length; j++) {  // j are columns
                let temp = [];
                for (let i = 0; i < mat.length; i++) {  // i are rows
                    temp.push(mat[i][j]);  // so temp will be the j(th) column in mat
                }
                newMat.push(temp);  // then just push every column in newMat
            }
            return newMat;
        }
    
    0 讨论(0)
  • 2020-11-22 02:12

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

    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>

    0 讨论(0)
  • 2020-11-22 02:13

    Since nobody so far mentioned a functional recursive approach here is my take. An adaptation of Haskell's Data.List.transpose.

    var transpose = as => as.length ? as[0].length ? [ as.reduce( (rs,a) => a.length ? ( rs.push(a[0])
                                                                                       , rs
                                                                                       )
                                                                                     : rs
                                                                , []
                                                                )
                                                     , ...transpose(as.map(a => a.slice(1)))
                                                     ]
                                                   : transpose(as.slice(1))
                                    : [],
        mtx       = [[1], [1, 2], [1, 2, 3]];
    
    console.log(transpose(mtx))
    .as-console-wrapper {
      max-height: 100% !important
    }

    0 讨论(0)
  • 2020-11-22 02:14

    If using RamdaJS is an option, this can be achieved in one line: R.transpose(myArray)

    0 讨论(0)
  • 2020-11-22 02:14

    I think this is slightly more readable. It uses Array.from and logic is identical to using nested loops:

    var arr = [
      [1, 2, 3, 4],
      [1, 2, 3, 4],
      [1, 2, 3, 4]
    ];
    
    /*
     * arr[0].length = 4 = number of result rows
     * arr.length = 3 = number of result cols
     */
    
    var result = Array.from({ length: arr[0].length }, function(x, row) {
      return Array.from({ length: arr.length }, function(x, col) {
        return arr[col][row];
      });
    });
    
    console.log(result);

    If you are dealing with arrays of unequal length you need to replace arr[0].length with something else:

    var arr = [
      [1, 2],
      [1, 2, 3],
      [1, 2, 3, 4]
    ];
    
    /*
     * arr[0].length = 4 = number of result rows
     * arr.length = 3 = number of result cols
     */
    
    var result = Array.from({ length: arr.reduce(function(max, item) { return item.length > max ? item.length : max; }, 0) }, function(x, row) {
      return Array.from({ length: arr.length }, function(x, col) {
        return arr[col][row];
      });
    });
    
    console.log(result);

    0 讨论(0)
提交回复
热议问题