Transposing a 2D-array in JavaScript

后端 未结 23 2788
难免孤独
难免孤独 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:22

    You can achieve this without loops by using the following.

    • Array
    • Array.prototype.map
    • Array.prototype.reduce
    • Array.prototype.join
    • String.prototype.split

    It looks very elegant and it does not require any dependencies such as jQuery of 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);
    }
    

    Minified

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

    Here is a demo I threw together. Notice the lack of loops :-)

    // 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(['
    '])); }
    #out {
        white-space: pre;
    }

提交回复
热议问题