你如何轻松创建空矩阵javascript?

时间:2011-11-28 19:44:19

标签: javascript

在python中,你可以这样做:

[([None] * 9) for x in range(9)]

你会得到这个:

[[None, None, None, None, None, None, None, None, None],
 [None, None, None, None, None, None, None, None, None],
 [None, None, None, None, None, None, None, None, None],
 [None, None, None, None, None, None, None, None, None],
 [None, None, None, None, None, None, None, None, None],
 [None, None, None, None, None, None, None, None, None],
 [None, None, None, None, None, None, None, None, None],
 [None, None, None, None, None, None, None, None, None],
 [None, None, None, None, None, None, None, None, None]]

如何在javascript中执行等效操作?

18 个答案:

答案 0 :(得分:56)

Array.fill

考虑使用fill

Array(9).fill().map(()=>Array(9).fill())

这里的想法是fill()会使用undefined填写项目,这足以让map对其进行处理。

你也可以直接填写:

Array(9).fill(Array(9))

Array(9).fill()的替代方案包括

Array(...Array(9))
[].push(...Array(9))
[].concat(Array(9))
Array.from(Array(9))

我们可以在语义上重写解决方案:

function array9() { return Array(9).fill(); }
array9().map(array9)

function array(n) { return Array(n).fill(); }
array(9).map(() => array(9))

Array.from为我们提供了一个可选的第二个映射参数,因此我们可以选择编写

Array.from(Array(9), () => Array.from(Array(9));

或者,如果您愿意

function array9(map) { return Array.from(Array(9), map); }
array9(array9);

有关详细说明和示例,请参阅Array.prototype.fill() here上的Mozilla文档。
以及Array.from()here

请注意,Array.prototype.fill()Array.from()都不支持Internet Explorer。上面的MDN链接提供了IE的polyfill。

分区

partition(Array(81), 9)

如果你有一个partition实用程序。这是一个快速递归的:

function partition(a, n) {
  return a.length ? [a.splice(0, n)].concat(partition(a, n)) : [];
}  

循环

我们可以使用

更有效地循环
var a = [], b;
while (a.push(b = []) < 9) while (b.push(null) < 9);

利用push返回新数组长度的事实。

答案 1 :(得分:53)

var matrix = [];
for(var i=0; i<9; i++) {
    matrix[i] = new Array(9);
}

......或:

var matrix = [];
for(var i=0; i<9; i++) {
    matrix[i] = [];
    for(var j=0; j<9; j++) {
        matrix[i][j] = undefined;
    }
}

答案 2 :(得分:10)

&#13;
&#13;
// initializing depending on i,j:
var M=Array.from({length:9}, (_,i) => Array.from({length:9}, (_,j) => i+'x'+j))

// Print it:

console.table(M)
// M.forEach(r => console.log(r))
document.body.innerHTML = `<pre>${M.map(r => r.join('\t')).join('\n')}</pre>`
// JSON.stringify(M, null, 2) // bad for matrices
&#13;
&#13;
&#13;

注意下面这样做是错误的:

// var M=Array(9).fill([]) // since arrays are sparse
// or Array(9).fill(Array(9).fill(0))// initialization

// M[4][4] = 1
// M[3][4] is now 1 too!

因为它创建了相同的数组引用次数9次,所以修改项目也修改了项目在其他行的相同索引处(因为它是相同的引用),所以你需要在行上额外调用.slice或.map来复制它们(参见torazaburo的答案,在此陷阱中失败)

注意:将来可能看起来像slice-notation-literal proposal (stage 1)

const M = [...1:10].map(i => [...1:10].map(j => i+'x'+j))

答案 3 :(得分:4)

如果您真的喜欢单行,并且项目中有underscore.js用途(这是一个很棒的库),您可以执行以下操作:

_.range(9).map(function(n) {
      return _.range(9).map(function(n) {
            return null;
      });
});

但我会选择上面提到的标准for-cycle版本。

答案 4 :(得分:3)

这是对你的问题的一个确切修复,但我建议不要使用表示'0'或'undefined'的默认值来初始化矩阵,因为javascript中的数组只是常规对象,所以你最终会浪费精力。 如果您想将单元格默认为某个有意义的值,那么此代码段将运行良好,但如果您需要未初始化的矩阵,请不要使用此版本

/**
* Generates a matrix (ie: 2-D Array) with: 
* 'm' columns, 
* 'n' rows, 
* every cell defaulting to 'd';
*/
function Matrix(m, n, d){
    var mat = Array.apply(null, new Array(m)).map(
        Array.prototype.valueOf,
        Array.apply(null, new Array(n)).map(
            function() {
               return d;
            }
        )
    );
    return mat;
}

用法:

< Matrix(3,2,'dobon');
> Array [ Array['dobon', 'dobon'], Array['dobon', 'dobon'], Array['dobon', 'dobon'] ]

如果您只想创建一个未初始化的二维数组,那么这比不必要地初始化每个条目更有效:

/**
* Generates a matrix (ie: 2-D Array) with: 
* 'm' columns, 
* 'n' rows, 
* every cell remains 'undefined';
*/
function Matrix(m, n){
    var mat = Array.apply(null, new Array(m)).map(
        Array.prototype.valueOf,
        new Array(n)
    );
    return mat;
}

用法:

< Matrix(3,2);
> Array [ Array[2], Array[2], Array[2] ]

答案 5 :(得分:2)

我需要提及Array.fill

如果您只是使用以下方法来创建3x3矩阵。

Array(3).fill(Array(3).fill(0));

您会发现矩阵中的值是参考。

enter image description here

优化解决方案(防止通过引用传递):

如果您希望通过值而不是引用进行传递,则可以使用Array.map来创建它。

Array(3).fill(null).map(() => Array(3).fill(0));

enter image description here

答案 6 :(得分:1)

对于二维矩阵,我会执行以下操作

var data = Array(9 * 9).fill(0);
var index = (i,j) => 9*i + j;
//any reference to an index, eg. (3,4) can be done as follows
data[index(3,4)]; 

您可以将 9 替换为任何通用 ROWS 和 COLUMNS 常量。

答案 7 :(得分:1)

问题略显模糊,因为None可以转化为undefinednullnull是更好的选择:

var a = [], b;
var i, j;
for (i = 0; i < 9; i++) {
  for (j = 0, b = []; j < 9; j++) {
    b.push(null);
  }
  a.push(b);
}

如果undefined,你可以马虎而且不要打扰,反正一切都是undefined。 :)

答案 8 :(得分:0)

这是一个,没有循环:

(Math.pow(10, 20)+'').replace((/0/g),'1').split('').map(parseFloat);

填写'20'作为长度,使用(可选)regexp进行方便的转换并映射以确保数据类型。 我在Array原型中添加了一个函数,可以轻松地将'map'的参数拉入你的函数中..有点冒险,有些人强烈反对触摸原生原型,但它确实派上用场了..

    Array.prototype.$args = function(idx) {
        idx || (idx = 0);
        return function() {
            return arguments.length > idx ? arguments[idx] : null;
        };
    };

// Keys
(Math.pow(10, 20)+'').replace((/0/g),'1').split('').map(this.$args(1));
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

// Matrix
(Math.pow(10, 9)+'').replace((/0/g),'1').split('').map(this.$args(1)).map(this.$args(2))

答案 9 :(得分:0)

Coffeescript救援!

[1..9].map -> [1..9].map -> null

答案 10 :(得分:0)

更好。完全可以。

let mx = Matrix(9, 9);

function Matrix(w, h){
    let mx = Array(w);
    for(let i of mx.keys())
        mx[i] = Array(h);
    return mx;
}


显示了什么

Array(9).fill(Array(9)); // Not correctly working

它不起作用,因为所有单元格都填充有一个数组

答案 11 :(得分:0)

JavaScript没有内置的2D数组概念,但是您当然可以创建一个数组数组。

function createMatrix(row, column, isEmpty) {
        let tmpMatrix = []
        let tmpArray = []
        let rowColumn = row * column
        for (let i = 1; i <= rowColumn; i++) {
            isEmpty ?  tmpArray.push('none') :  tmpArray.push(i)

            if (i % column === 0) {
                tmpMatrix.push(tmpArray)
                tmpArray = []
            }
        }
        return tmpMatrix
    }

createMatrix(5, 3, true)

function createMatrix(row, column, from) {

        let [matrix, array] = [[], []],
            total = row * column

        for (let element = from || 1; element <= total; element++) {
            array.push(element)
            if (element % column === 0) {
                matrix.push(array)
                array = []
            }
        }

        return matrix
    }

createMatrix(5, 6, 1)

答案 12 :(得分:0)

使用此功能或类似功能。 :)

function createMatrix(line, col, defaultValue = 0){ 
    return new Array(line).fill(defaultValue).map((x)=>{ return new Array(col).fill(defaultValue); return x; }); 
}
var myMatrix = createMatrix(9,9);

答案 13 :(得分:-1)

我也会给它拍摄

var c = Array;

for( var i = 0, a = c(9); i < 9; a[i] = c(9), i++ );

console.log( a.join(",") );
//",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"

可读且易于维护!

答案 14 :(得分:-1)

您可以通过扩展其prototype对象来为数组添加功能。

Array.prototype.nullify = function( n ) {
    n = n >>> 0;
    for( var i = 0; i < n; ++i ) {
        this[ i ] = null;
    }
    return this;
};

然后:

var arr = [].nullify(9);

或:

var arr = [].nullify(9).map(function() { return [].nullify(9); });

答案 15 :(得分:-1)

Array.from(new Array(row), () => new Array(col).fill(0));

答案 16 :(得分:-1)

好吧,你可以使用显式数组构造函数创建一个空的 1-D 数组:

a = new Array(9)

要创建一个数组数组,我认为你必须像Marc所描述的那样编写一个嵌套循环。

答案 17 :(得分:-2)

使用ES6传播算子: find /Users/username/junk/ -mindepth 2 -maxdepth 2 -type f \ -name '*.*' -not -name '*.mid' -exec sh -c 'mv -v "$1" "$1.mid"' -- {} \;