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中执行等效操作?
14 个解决方案
#1
43
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;
}
}
#2
43
Array.fill
Consider using 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()将填充未定义的项目,这足以让地图对它们起作用。
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.
有关详细说明和示例,请参阅此处的Mozilla Docs on Array.prototype.fill()。对于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()都不支持。上述MDN链接提供了IE的polyfill。
Partitioning
partition(Array(81), 9)
if you have a partition
utility handy. Here's a quick recursive one:
如果你有一个分区实用程序方便。这是一个快速递归的:
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返回新数组长度的事实。
#3
9
// 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 also items 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 failed in this trap)
因为它创建了相同的数组引用次数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))
#4
4
If you really like one-liners and there is a use for underscore.js in 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版本。
#5
2
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'或'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;
}
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] ]
#6
1
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. :)
如果未定义,你可以马虎而且不要打扰,无论如何一切都是未定义的。 :)
#7
1
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));
#8
0
Coffeescript to the rescue!
Coffeescript救援!
[1..9].map -> [1..9].map -> null
[1..9] .map - > [1..9] .map - > null
#9
0
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))
#10
0
I like using strings for this
我喜欢使用字符串
Strings can be repeated with the function repeat. Those can be mapped to change it's values, which then can be optionaly mapped to set default values. I chose undefined in this case.
可以使用函数repeat重复字符串。可以映射这些值以更改它的值,然后可以选择映射以设置默认值。在这种情况下我选择了undefined。
Array.fill is nice too, but I wanted to show another alternative.
Array.fill也很好,但我想展示另一种选择。
var matrix = ".".repeat(8).split(".").map( s=> {return ".".repeat(8).split(".").map(s => {return undefined})});
console.log(matrix);
#11
0
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
它不起作用,因为所有单元格都填充了一个数组
#12
-1
Well, you can create an empty 1-D array using the explicit Array constructor:
那么,您可以使用显式Array构造函数创建一个空的1-D数组:
a = new Array(9)
a =新数组(9)
To create an array of arrays, I think that you'll have to write a nested loop as Marc described.
要创建一个数组数组,我认为你必须像Marc描述的那样编写一个嵌套循环。
#13
-1
You can add functionality to an Array by extending its prototype
object.
您可以通过扩展其原型对象来向Array添加功能。
Array.prototype.nullify = function( n ) {
n = n >>> 0;
for( var i = 0; i < n; ++i ) {
this[ i ] = null;
}
return this;
};
Then:
var arr = [].nullify(9);
or:
var arr = [].nullify(9).map(function() { return [].nullify(9); });
#14
-1
I'll give it my shot as well
我也会把它给我的镜头
var c = Array;
for( var i = 0, a = c(9); i < 9; a[i] = c(9), i++ );
console.log( a.join(",") );
//",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"
Readable and maintainable !
可读和可维护!
#1
43
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;
}
}
#2
43
Array.fill
Consider using 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()将填充未定义的项目,这足以让地图对它们起作用。
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.
有关详细说明和示例,请参阅此处的Mozilla Docs on Array.prototype.fill()。对于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()都不支持。上述MDN链接提供了IE的polyfill。
Partitioning
partition(Array(81), 9)
if you have a partition
utility handy. Here's a quick recursive one:
如果你有一个分区实用程序方便。这是一个快速递归的:
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返回新数组长度的事实。
#3
9
// 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 also items 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 failed in this trap)
因为它创建了相同的数组引用次数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))
#4
4
If you really like one-liners and there is a use for underscore.js in 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版本。
#5
2
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'或'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;
}
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] ]
#6
1
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. :)
如果未定义,你可以马虎而且不要打扰,无论如何一切都是未定义的。 :)
#7
1
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));
#8
0
Coffeescript to the rescue!
Coffeescript救援!
[1..9].map -> [1..9].map -> null
[1..9] .map - > [1..9] .map - > null
#9
0
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))
#10
0
I like using strings for this
我喜欢使用字符串
Strings can be repeated with the function repeat. Those can be mapped to change it's values, which then can be optionaly mapped to set default values. I chose undefined in this case.
可以使用函数repeat重复字符串。可以映射这些值以更改它的值,然后可以选择映射以设置默认值。在这种情况下我选择了undefined。
Array.fill is nice too, but I wanted to show another alternative.
Array.fill也很好,但我想展示另一种选择。
var matrix = ".".repeat(8).split(".").map( s=> {return ".".repeat(8).split(".").map(s => {return undefined})});
console.log(matrix);
#11
0
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
它不起作用,因为所有单元格都填充了一个数组
#12
-1
Well, you can create an empty 1-D array using the explicit Array constructor:
那么,您可以使用显式Array构造函数创建一个空的1-D数组:
a = new Array(9)
a =新数组(9)
To create an array of arrays, I think that you'll have to write a nested loop as Marc described.
要创建一个数组数组,我认为你必须像Marc描述的那样编写一个嵌套循环。
#13
-1
You can add functionality to an Array by extending its prototype
object.
您可以通过扩展其原型对象来向Array添加功能。
Array.prototype.nullify = function( n ) {
n = n >>> 0;
for( var i = 0; i < n; ++i ) {
this[ i ] = null;
}
return this;
};
Then:
var arr = [].nullify(9);
or:
var arr = [].nullify(9).map(function() { return [].nullify(9); });
#14
-1
I'll give it my shot as well
我也会把它给我的镜头
var c = Array;
for( var i = 0, a = c(9); i < 9; a[i] = c(9), i++ );
console.log( a.join(",") );
//",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"
Readable and maintainable !
可读和可维护!