你如何轻松地创建空矩阵 javascript?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8301400/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you easily create empty matrices javascript?
提问by priestc
In python, you can do this:
在python中,你可以这样做:
[([None] * 9) for x in range(9)]
and you'll get this:
你会得到这个:
[[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]]
How can I do the equivalent in javascript?
我怎样才能在javascript中做等价的?
回答by
Array.fill
Array.fill
Consider using fill
:
考虑使用fill
:
Array(9).fill().map(()=>Array(9).fill())
The idea here is that fill()
will fill out the items with undefined
, which is enough to get map
to work on them.
这里的想法是用fill()
填充项目undefined
,这足以开始map
处理它们。
You could also fill directly:
也可以直接填写:
Array(9).fill(Array(9))
Alternatives to Array(9).fill()
include
Array(9).fill()
包括的替代方案
Array(...Array(9))
[].push(...Array(9))
[].concat(Array(9))
Array.from(Array(9))
We can rewrite the solution a bit more semantically as:
我们可以更语义地重写解决方案,如下所示:
function array9() { return Array(9).fill(); }
array9().map(array9)
or
或者
function array(n) { return Array(n).fill(); }
array(9).map(() => array(9))
Array.from
provides us with an optional second mapping argument, so we have the alternative of writing
Array.from
为我们提供了一个可选的第二个映射参数,因此我们可以选择编写
Array.from(Array(9), () => Array.from(Array(9));
or, if you prefer
或者,如果您愿意
function array9(map) { return Array.from(Array(9), map); }
array9(array9);
For verbose description and examples, see Mozilla's Docs on Array.prototype.fill()
here.
and for Array.from()
, here.
有关详细说明和示例,请参阅Array.prototype.fill()
此处的Mozilla 文档。
对于Array.from()
,这里。
Note that neither Array.prototype.fill()
nor Array.from()
has support in Internet Explorer. A polyfill for IE is available at the above MDN links.
请注意,Internet Explorer中既不支持Array.prototype.fill()
也不Array.from()
支持。IE 的 polyfill 可在上述 MDN 链接中找到。
Partitioning
分区
partition(Array(81), 9)
if you have a partition
utility handy. Here's a quick recursive one:
如果您手头有partition
实用程序。这是一个快速递归的:
function partition(a, n) {
return a.length ? [a.splice(0, n)].concat(partition(a, n)) : [];
}
Looping
循环
We can loop a bit more efficiently with
我们可以更有效地循环
var a = [], b;
while (a.push(b = []) < 9) while (b.push(null) < 9);
Taking advantage of the fact that push
returns the new array length.
利用push
返回新数组长度的事实。
回答by Richard JP Le Guen
var matrix = [];
for(var i=0; i<9; i++) {
matrix[i] = new Array(9);
}
... or:
... 或者:
var matrix = [];
for(var i=0; i<9; i++) {
matrix[i] = [];
for(var j=0; j<9; j++) {
matrix[i][j] = undefined;
}
}
回答by caub
// 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
Beware that doing this below, is wrong:
请注意,在下面执行此操作是错误的:
// 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!
Because it creates the same reference of Array 9 times, so modifying an item modifies alsoitems at the same index of other rows (since it's the same reference), so you need an additional call to .slice or .map on the rows to copy them (cf torazaburo's answer which fell in this trap)
因为它创建了 Array 9 次相同的引用,所以修改一个项目也会修改其他行的相同索引处的项目(因为它是相同的引用),所以你需要在行上额外调用 .slice 或 .map 进行复制他们(参见落入这个陷阱的 torazaburo 的回答)
note:It may look like this in the future, with slice-notation-literal proposal (stage 1)
注意:将来可能看起来像这样,带有切片符号文字建议(阶段 1)
const M = [...1:10].map(i => [...1:10].map(j => i+'x'+j))
回答by HectorGuo
There is something about Array.fill
I need to mention.
有一点Array.fill
我需要提一下。
If you just use below method to create a 3x3 matrix.
如果您只是使用下面的方法来创建一个 3x3 矩阵。
Array(3).fill(Array(3).fill(0));
You will find that the values in the matrix is a reference.
您会发现矩阵中的值是一个参考。
Optimized solution (prevent passing by reference):
优化方案(防止引用传递):
If you want to pass by value rather than reference, you can leverage Array.map
to create it.
如果你想通过值而不是引用传递,你可以利用Array.map
它来创建它。
Array(3).fill(null).map(() => Array(3).fill(0));
回答by kubetz
If you reallylike one-liners and there is a use for underscore.jsin your project (which is a great library) you can do write-only things like:
如果你真的喜欢单行并且在你的项目中使用underscore.js(这是一个很棒的库),你可以做只写的事情,比如:
_.range(9).map(function(n) {
return _.range(9).map(function(n) {
return null;
});
});
But I would go with standard for-cycle version mentioned above.
但我会选择上面提到的标准 for-cycle 版本。
回答by dobon
This is an exact fix to your problem, but I would advise against initializing the matrix with a default value that represents '0' or 'undefined', as Arrays in javascript are just regular objects, so you wind up wasting effort. If you want to default the cells to some meaningful value, then this snippet will work well, but if you want an uninitialized matrix, don't use this version:
这是对您的问题的精确修复,但我建议不要使用代表“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;
}
Usage:
用法:
< Matrix(3,2,'dobon');
> Array [ Array['dobon', 'dobon'], Array['dobon', 'dobon'], Array['dobon', 'dobon'] ]
If you would rather just create an uninitialized 2-D Array, then this will be more efficient than unnecessarily initializing every entry:
如果您只想创建一个未初始化的二维数组,那么这将比不必要地初始化每个条目更有效:
/**
* 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;
}
Usage:
用法:
< Matrix(3,2);
> Array [ Array[2], Array[2], Array[2] ]
回答by Amadan
The question is slightly ambiguous, since None
can translate into either undefined
or null
. null
is a better choice:
这个问题有点模棱两可,因为None
可以转换为undefined
或null
。null
是更好的选择:
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);
}
If undefined
, you can be sloppy and just don't bother, everything is undefined
anyway. :)
如果undefined
,你可以马虎,只是不打扰,undefined
反正一切。:)
回答by Erik Schoel
Here's one, no looping:
这是一个,没有循环:
(Math.pow(10, 20)+'').replace((/0/g),'1').split('').map(parseFloat);
Fill the '20' for length, use the (optional) regexp for handy transforms and map to ensure datatype. 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..
填充“20”作为长度,使用(可选)正则表达式进行方便的转换和映射以确保数据类型。我在 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))
回答by Данила Летуновский
better. that exactly will work.
更好的。这确实会起作用。
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;
}
what was shown
显示了什么
Array(9).fill(Array(9)); // Not correctly working
It does not work, because all cells are fill with one array
它不起作用,因为所有单元格都填充了一个数组
回答by Driton Haxhiu
JavaScript doesn't have a built-in 2D array concept, but you can certainly create an array of arrays.
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)
or
或者
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)