如何轻松地创建空矩阵 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 中做相同的事情?

176189 次浏览
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;
}
}

您可以使用显式 Array 构造函数创建一个空的 1-D数组:

a = new Array(9)

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

可以通过扩展 Array 的 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); });

这个问题有点模棱两可,因为 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。 :)

如果您喜欢一行程序,并且在您的项目中(这是一个很棒的库)使用了 下划线 js,那么您可以执行只写操作,比如:

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

但是我会选择上面提到的标准的循环版本。

咖啡手稿来救场了!

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

我也要试试

var c = Array;


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


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

可读性和可维护性!

这是一个精确的解决你的问题的方法,但是我建议不要用默认值表示“0”或“未定义”来初始化矩阵,因为 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'] ]

如果您想创建一个未初始化的2-D Array,那么这将比不必要地初始化每个条目 更有效:

/**
* 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] ]

这里有一个,没有循环:

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

为长度填充“20”,使用(可选) regexp 进行方便的转换并映射以确保数据类型。 I added a function to the Array prototype to easily pull the parameters of 'map' into your functions.. bit risky, some people strongly oppose touching native prototypes, but it does come in handy..

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

// 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

请注意,这样做是错误的:

// 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!

因为它创建了相同的 Array 9次引用,所以在其他行的相同索引处修改一个项 也可以修改项(因为它是相同的引用) ,所以需要额外调用。切片或。在行上映射以复制它们(参见 torazaburo 的回答,落入了这个陷阱)

注意: 将来可能会是这样,比如说 Number.range ()提案

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

Array.fill

考虑使用 fill:

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

这里的想法是 fill()将用 undefined填写这些项目,这足以让 map处理它们。

你也可以直接填写:

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

(重要提示: Array(9).fill(Array(9)) < em > 将用相同的数组填充数组的每一行,因此更改一行将更改其他行)。

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() 给你上的 Mozilla 文档。
以及 Array.from()给你

请注意,无论是 Array.prototype.fill()还是 Array.from()都没有 Internet Explorer 支持。IE 的填充物可以在上面的 MDN 链接中找到。

分区

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返回新数组长度这一事实。

有一些关于 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

好多了,这样就行了。

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

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

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

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


if (i % column === 0) {
matrix.push(array)
array = []
}
}
return matrix
}


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)

使用这个函数或类似的函数。 :)

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

对于二维矩阵,我会做如下操作

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

可以使用任何泛型 ROWS 和 COLUMNS 常量替换 9

const dim1 = 9
const dim2 = 9
const init = 0
const matrix = Array.from({length:dim1}, _=>Array(dim2).fill(init))