我一直在网上阅读,有些地方说不可能,有些说不可能,然后举个例子,其他人反驳这个例子,等等。
如何在 JavaScript 中声明二维数组? (假设可能)我将如何访问其成员? (myArray[0][1] 还是 myArray[0,1]?)
var arr2D = new Array(5).fill(new Array(3));
用更多数组填充数组时,Array(5) 的每个元素都将指向同一个 Array(3)。所以最好使用for循环来动态填充子数组。
a = Array(5).fill(0).map(x => Array(10).fill(0))
fill
不会为要填充的数组的每个索引调用 new Array(3)
,因为它不是 lambda 表达式或任何东西,例如上面吴龙飞的评论,它最初用 0 填充数组,然后使用带有 lambda 的 map 函数以用新数组填充每个元素。填充函数只是用你告诉它的内容填充数组。那有意义吗?有关 map
函数的详细信息,请参阅:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
If the new question is a better question or has better answers, then vote to close the old one as a duplicate of the new one.
var items = [ [1, 2], [3, 4], [5, 6] ]; console.log(items[0][0]); // 1 console.log(items[0][1]); // 2 console.log(items[1][0]); // 3 console.log(items[1][1]); // 4 console.log(items);
您只需将数组中的每个项目都设为数组。
var x = 新数组(10); for (var i = 0; i < x.length; i++) { x[i] = new Array(3); } 控制台.log(x);
new Array(size)
其中 size
是一个变量。
与 activa 的回答类似,这里有一个创建 n 维数组的函数:
function createArray(length) {
var arr = new Array(length || 0),
i = length;
if (arguments.length > 1) {
var args = Array.prototype.slice.call(arguments, 1);
while(i--) arr[length-1 - i] = createArray.apply(this, args);
}
return arr;
}
createArray(); // [] or new Array()
createArray(2); // new Array(2)
createArray(3, 2); // [new Array(2),
// new Array(2),
// new Array(2)]
var array = createArray(2, 3, 4, 5);
。
[[[[[null,null],[null,null]],[[null,null],[null,null]]],[[[null,null],[null,null]],[[null,null],[null,null]]]],[[[[null,null],[null,null]],[[null,null],[null,null]]],[[[null,null],[null,null]],[[null,null],[null,null]]]]]
如何创建一个空的二维数组(一行)
Array.from(Array(2), () => new Array(4))
2和4分别是第一和第二维度。
我们正在使用 Array.from
,它可以采用类似数组的参数和每个元素的可选映射。
Array.from(arrayLike[, mapFn[, thisArg]])
var arr = Array.from(Array(2), () => new Array(4)); arr[0][0] = 'foo';控制台信息(arr);
同样的技巧可以用来Create a JavaScript array containing 1...N
或者(但在 n = 10,000 时效率更低,为 12%)
Array(2).fill(null).map(() => Array(4))
性能下降的原因是我们必须初始化第一个维度值才能运行 .map
。请记住,在您通过 .fill
或直接赋值之前,Array
不会分配位置。
var arr = Array(2).fill(null).map(() => Array(4)); arr[0][0] = 'foo';控制台信息(arr);
跟进
这是一种看起来正确但有问题的方法。
Array(2).fill(Array(4)); // BAD! Rows are copied by reference
虽然它确实返回了显然需要的二维数组 ([ [ <4 empty items> ], [ <4 empty items> ] ]
),但有一个问题:第一维数组已通过引用复制。这意味着 arr[0][0] = 'foo'
实际上会更改两行而不是一行。
var arr = Array(2).fill(Array(4)); arr[0][0] = 'foo';控制台信息(arr);控制台信息(arr[0][0],arr[1][0]);
Array.from({length:5}, () => [])
Array.from(Array(2), () => new Array(4))
和 Array.from(Array(2), () => Array(4))
有什么区别?
Javascript只有一维数组,但您可以构建数组的数组,正如其他人指出的那样。
以下函数可用于构造固定维度的二维数组:
function Create2DArray(rows) {
var arr = [];
for (var i=0;i<rows;i++) {
arr[i] = [];
}
return arr;
}
列数并不是很重要,因为在使用它之前不需要指定数组的大小。
然后你可以打电话:
var arr = Create2DArray(100);
arr[50][2] = 5;
arr[70][5] = 7454;
// ...
最简单的方法:
var myArray = [[]];
myArray[1][0]=5;
之前设置 myArray[1]=[];
myArray.length == 1
和 myArray[0].length == 0
。如果您随后将“真正空的”“0x0”数组复制到其中,则会给出错误的结果。
有人说不可能的原因是因为二维数组实际上只是一个数组数组。这里的其他评论提供了在 JavaScript 中创建二维数组的完全有效的方法,但最纯粹的观点是你有一个一维对象数组,每个对象都是一个由两个元素组成的一维数组。
所以,这就是观点冲突的原因。
string[3,5] = "foo";
这样的多维数组。对于某些情况,这是一种更好的方法,因为 Y 轴实际上不是 X 轴的子轴。
很少有人展示 push 的使用:为了带来新的东西,我将向您展示如何使用一些值初始化矩阵,例如:0 或空字符串“”。提醒一下,如果你有一个 10 个元素的数组,在 javascript 中最后一个索引将是 9!
function matrix( rows, cols, defaultValue){
var arr = [];
// Creates all lines:
for(var i=0; i < rows; i++){
// Creates an empty line
arr.push([]);
// Adds cols to the empty line:
arr[i].push( new Array(cols));
for(var j=0; j < cols; j++){
// Initializes:
arr[i][j] = defaultValue;
}
}
return arr;
}
用法示例:
x = matrix( 2 , 3,''); // 2 lines, 3 cols filled with empty string
y = matrix( 10, 5, 0);// 10 lines, 5 cols filled with 0
for
(设置默认值)并写入 m=matrix(3,4); m[1][2]=2; console.log(JSON.stringify(m));
- 我们得到了非常战略矩阵(嵌套太多) - 你在最后一个 for-defaultValue 步骤中修复它,但我认为你可以重写过程在设置默认值之前使用较少的嵌套数组。
两线:
var a = [];
while(a.push([]) < 10);
它将生成一个长度为 10 的数组 a,其中填充了数组。 (Push 向数组中添加一个元素并返回新的长度)
for (var a=[]; a.push([])<10;);
?
var
就是这样工作的。它始终是函数范围的。
最明智的答案似乎是
var nrows = ~~(Math.random() * 10); var ncols = ~~(Math.random() * 10); console.log(`rows:${nrows}`); console.log(`cols:${ncols}`); var matrix = new Array(nrows).fill(0).map(row => new Array(ncols).fill(0));控制台.log(矩阵);
请注意,我们不能直接填充行,因为填充使用浅拷贝构造函数,因此所有行将共享相同的内存......这是演示如何共享每行的示例(取自其他答案):
// DON'T do this: each row in arr, is shared
var arr = Array(2).fill(Array(4));
arr[0][0] = 'foo'; // also modifies arr[1][0]
console.info(arr);
Array.apply(null, Array(nrows))
做了类似的事情,但这更优雅。
fill
。这不适用于大多数浏览器。
Array(nrows).map(() => 0)
,或者,Array(nrows).map(function(){ return 0; });
最简单的方法:
var arr = [];
var arr1 = ['00','01'];
var arr2 = ['10','11'];
var arr3 = ['20','21'];
arr.push(arr1);
arr.push(arr2);
arr.push(arr3);
alert(arr[0][1]); // '01'
alert(arr[1][1]); // '11'
alert(arr[2][0]); // '20'
表现
今天 2020.02.05 我在 Chrome v79.0、Safari v13.0.4 和 Firefox v72.0 上对 MacOs HighSierra 10.13.6 进行测试,以选择解决方案。
非初始化二维数组的结论
深奥的解决方案 {}/arr[[i,j]] (N) 对于大小数组来说是最快的,看起来它是大稀疏数组的不错选择
基于 for-[]/while (A,G) 的解决方案速度很快,它们是小型数组的不错选择。
-[] (B,C) 的解决方案速度很快,它们是大型数组的不错选择
基于 Array..map/from/fill (I,J,K,L,M) 的解决方案对于小型阵列非常慢,对于大型阵列则非常快
令人惊讶的是 for-Array(n) (B,C) 在 safari 上比 for-[] (A) 慢得多
令人惊讶的是 for-[] (A) for big array 在所有浏览器上都很慢
解决方案 K 对于所有浏览器的小数组都很慢
对于所有浏览器的大数组,解决方案 A、E、G 都很慢
对于所有浏览器上的所有数组,解决方案 M 最慢
https://i.stack.imgur.com/YD4S1.png
初始化二维数组的结论
基于 for/while (A,B,C,D,E,G) 的解决方案对于所有浏览器上的小型数组来说都是最快/相当快的
基于 for (A,B,C,E) 的解决方案对于所有浏览器上的大数组来说都是最快/相当快的
基于 Array..map/from/fill (I,J,K,L,M) 的解决方案对于所有浏览器上的小型数组来说都是中等速度或慢速
大型阵列的解决方案 F、G、H、I、J、K、L 在 chrome 和 safari 上中等或快速,但在 Firefox 上最慢。
深奥的解决方案 {}/arr[[i,j]] (N) 对于所有浏览器上的大小数组来说都是最慢的
https://i.stack.imgur.com/y0zh2.png
细节
测试未填充(初始化)输出数组的解决方案
我们测试解决方案的速度
小数组(12 个元素) - 你可以在你的机器上执行测试 这里
大数组(100 万个元素)数组 - 您可以在此处的机器上执行测试
函数 A(r) { var arr = []; for (var i = 0; i < r; i++) arr[i] = [];返回 arr; } 函数 B(r, c) { var arr = new Array(r); for (var i = 0; i < arr.length; i++) arr[i] = new Array(c);返回 arr; } 函数 C(r, c) { var arr = Array(r); for (var i = 0; i < arr.length; i++) arr[i] = Array(c);返回 arr; } function D(r, c) { // 很奇怪,但是有效 var arr = []; for (var i = 0; i < r; i++) { arr.push([]); arr[i].push(数组(c)); } 返回 arr; } 函数 E(r, c) { 让数组 = [[]]; for (var x = 0; x < c; x++) { 数组[x] = []; for (var y = 0; y < r; y++) 数组[x][y] = [0]; } 返回数组; } function F(r, c) { var makeArray = function(dims, arr) { if (dims[1] === undefined) { return Array(dims[0]); } arr = Array(dims[0]); for (var i = 0; i < dims[0]; i++) { arr[i] = Array(dims[1]); arr[i] = makeArray(dims.slice(1), arr[i]); } 返回 arr; } 返回 makeArray([r, c]); } 函数 G(r) { var a = [];而 (a.push([]) < r);返回一个; } 函数 H(r,c) { 函数 createArray(length) { var arr = new Array(length || 0), i = length; if (arguments.length > 1) { var args = Array.prototype.slice.call(arguments, 1); while(i--) arr[length-1 - i] = createArray.apply(this, args); } 返回 arr; } 返回 createArray(r,c); } 函数 I(r, c) { return [...Array(r)].map(x => Array(c)); } function J(r, c) { return Array(r).fill(0).map(() => Array(c)); } function K(r, c) { return Array.from(Array(r), () => Array(c)); } function L(r, c) { return Array.from({length: r}).map(e => Array(c)); } function M(r, c) { return Array.from({length: r}, () => Array.from({length: c}, () => {})); } function N(r, c) { return {} } // ------------------------------------ - - - - - - // 节目 // - - - - - - - - - - - - - - - - - -------------- log = (t, f) => { let A = f(3, 4); // 创建 3 行 4 列的数组 A[1][2] = 6 // 第 2 行第 3 列设置为 6 console.log(`${t}[1][2]: ${A[ 1][2]},完整:${JSON.stringify(A).replace(/null/g,'x')}`); } log2 = (t, f) => { 让 A = f(3, 4); // 创建 3 行 4 列的数组 A[[1,2]] = 6 // 第 2 行第 3 列设置为 6 console.log(`${t}[1][2]: ${A [[1,2]]},完整:${JSON.stringify(A).replace(/null/g,'x')}`); } 日志('A',A);日志('B',B);日志('C',C);日志('D',D);日志('E',E);日志('F',F);日志('G',G);日志('H',H);日志('我',我);日志('J',J);日志('K',K);日志('L',L);日志('M',M); log2('N', N);这是解决方案的介绍 - 不是基准
测试填充(初始化)输出数组的解决方案
我们测试解决方案的速度
小数组(12 个元素) - 你可以在你的机器上执行测试 这里
大数组(100 万个元素)数组 - 您可以在此处的机器上执行测试
函数 A(r, c, def) { var arr = []; for (var i = 0; i < r; i++) arr[i] = Array(c).fill(def);返回 arr; } 函数 B(r, c, def) { var arr = new Array(r); for (var i = 0; i < arr.length; i++) arr[i] = new Array(c).fill(def);返回 arr; } 函数 C(r, c, def) { var arr = Array(r); for (var i = 0; i < arr.length; i++) arr[i] = Array(c).fill(def);返回 arr; } function D(r, c, def) { // 很奇怪,但是有效 var arr = []; for (var i = 0; i < r; i++) { arr.push([]); arr[i].push(数组(c)); } for (var i = 0; i < r; i++) for (var j = 0; j < c; j++) arr[i][j]=def return arr; } 函数 E(r, c, def) { 让数组 = [[]]; for (var x = 0; x < c; x++) { 数组[x] = []; for (var y = 0; y < r; y++) 数组[x][y] = def; } 返回数组; } function F(r, c, def) { var makeArray = function(dims, arr) { if (dims[1] === undefined) { return Array(dims[0]).fill(def); } arr = Array(dims[0]); for (var i = 0; i < dims[0]; i++) { arr[i] = Array(dims[1]); arr[i] = makeArray(dims.slice(1), arr[i]); } 返回 arr; } 返回 makeArray([r, c]); } 函数 G(r, c, def) { var a = []; while (a.push(Array(c).fill(def)) < r);返回一个; } function H(r,c, def) { function createArray(length) { var arr = new Array(length || 0), i = length; if (arguments.length > 1) { var args = Array.prototype.slice.call(arguments, 1); while(i--) arr[length-1 - i] = createArray.apply(this, args).fill(def); } 返回 arr; } 返回 createArray(r,c); } 函数 I(r, c, def) { return [...Array(r)].map(x => Array(c).fill(def)); } function J(r, c, def) { return Array(r).fill(0).map(() => Array(c).fill(def)); } function K(r, c, def) { return Array.from(Array(r), () => Array(c).fill(def)); } function L(r, c, def) { return Array.from({length: r}).map(e => Array(c).fill(def)); } function M(r, c, def) { return Array.from({length: r}, () => Array.from({length: c}, () => def)); } 函数 N(r, c, def) { 让 arr={}; for (var i = 0; i < r; i++) for (var j = 0; j < c; j++) arr[[i,j]]=def;返回 arr; } // ------------------------------------------------------------ // 节目 // - - - - - - - - - - - - - - - - - - - - - - - -- log = (t, f) => { 让 A = f(1000,1000,7); // 创建包含 1000 行和 1000 列的数组, // 每个数组单元由 7 初始化 A[800][900] = 5 // 第 800 行和第 901 列设置为 5 console.log(`${t}[1] [2]: ${A[1][2]}, ${t}[800][901]: ${A[800][900]}`); } log2 = (t, f) => { 让 A = f(1000,1000,7); // 创建 1000 行 1000 列的数组, // 每个数组单元由 7 初始化 A[[800,900]] = 5 // 第 800 行第 900 列设置为 5 console.log(`${t}[1][2 ]: ${A[[1,2]]}, ${t}[800][900]: ${A[[800,900]]}`); } 日志('A',A);日志('B',B);日志('C',C);日志('D',D);日志('E',E);日志('F',F);日志('G',G);日志('H',H);日志('我',我);日志('J',J);日志('K',K);日志('L',L);日志('M',M); log2('N', N);这是解决方案的介绍 - 不是基准
https://i.stack.imgur.com/oBoCA.png
要创建 4x6 数组,只需执行此操作
const x = [...new Array(6)].map(elem => new Array(4))
从空数组开始通常是一个好习惯,而不是填充 w 随机值。 (您通常在一维中将数组声明为 const x = []
,因此最好在二维中以空开头。)
这就是我所取得的成就:
var appVar = [[]]; appVar[0][4] = "bineesh"; appVar[0][5] = "库马尔"; console.log(appVar[0][4] + appVar[0][5]);控制台.log(appVar);
这拼写了我bineeshkumar
appVar[1][4] = "bineesh";
是错误的,如何解决呢?
二维数组的创建方式与一维数组的创建方式相同。您可以像 array[0][1]
一样访问它们。
var arr = [1, 2, [3, 4], 5];
alert (arr[2][1]); //alerts "4"
我不确定是否有人回答了这个问题,但我发现这对我很有效 -
var array = [[,],[,]]
例如:
var a = [[1,2],[3,4]]
例如,对于二维数组。
var array = [[],[]]
就足够了。
要创建一个所有索引可寻址且值设置为 null 的非稀疏“2D”数组 (x,y):
let 2Darray = new Array(x).fill(null).map(item =>(new Array(y).fill(null)))
奖励“3D”数组(x,y,z)
let 3Darray = new Array(x).fill(null).map(item=>(new Array(y).fill(null)).map(item=>Array(z).fill(null)))
对此问题的评论和不同点都提到了对此的变化和更正,但不是作为实际答案,所以我在这里添加它。
应该注意的是(类似于大多数其他答案)这具有 O(x*y) 时间复杂度,因此它可能不适合非常大的数组。
fill
设置了相同的值。如果将 null
更改为 `object 它将是每一列中的相同对象
let 2Darray = new Array(x).fill(null).map(item =>(new Array(y).fill(null).map(cell =>(yourValueHere))))
要在 JavaScript 中创建二维数组,我们可以先创建一个数组,然后添加数组作为元素。此方法将返回具有给定行数和列数的二维数组。
function Create2DArray(rows,columns) {
var x = new Array(rows);
for (var i = 0; i < rows; i++) {
x[i] = new Array(columns);
}
return x;
}
要创建一个数组,请使用以下方法。
var array = Create2DArray(10,20);
对于一个班轮爱好者Array.from()
// creates 8x8 array filed with "0"
const arr2d = Array.from({ length: 8 }, () => Array.from({ length: 8 }, () => "0"))
另一个(来自 dmitry_romanov 的评论)使用 Array().fill()
// creates 8x8 array filed with "0"
const arr2d = Array(8).fill(0).map(() => Array(8).fill("0"))
使用 ES6+ spread 运算符(InspiredJW answer 的“启发” :))
// same as above just a little shorter
const arr2d = [...Array(8)].map(() => Array(8).fill("0"))
fill()
函数中删除 0
:const arr2d = Array(8).fill().map(() => Array(8).fill("0"));
使用数组理解
在 JavaScript 1.7 及更高版本中,您可以使用数组解析来创建二维数组。您还可以在填充数组时过滤和/或操作条目,而不必使用循环。
var rows = [1, 2, 3];
var cols = ["a", "b", "c", "d"];
var grid = [ for (r of rows) [ for (c of cols) r+c ] ];
/*
grid = [
["1a","1b","1c","1d"],
["2a","2b","2c","2d"],
["3a","3b","3c","3d"]
]
*/
您可以创建任何您想要的 n x m
数组,并通过调用将其填充为默认值
var default = 0; // your 2d array will be filled with this value
var n_dim = 2;
var m_dim = 7;
var arr = [ for (n of Array(n_dim)) [ for (m of Array(m_dim) default ]]
/*
arr = [
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
]
*/
可以在 here 中找到更多示例和文档。
请注意,这还不是标准功能。
for
语句仍然是一个循环......
Array(m).fill(v).map(() => Array(n).fill(v))
您可以创建一个初始值为 m
的二维数组 m x n
,n
可以是任何数字 v
可以是任何值 string
、number
、undefined
。
一种方法可以是var a = [m][n]
只有在运行时才知道的数组的行和列大小,然后以下方法可用于创建动态二维数组。
变量编号 = '123456';变量行 = 3; // 运行时已知 var col = 2; // 运行时已知 var i = 0; var array2D = [[]]; for(var r = 0; r < 行; ++r) { array2D[r] = []; for(var c = 0; c < col; ++c) { array2D[r][c] = num[i++]; } } console.log(array2D); // [[ '1', '2' ], // [ '3', '4' ], // [ '5', '6' ]] console.log(array2D[2][1]); // 6
我的方法与@Bineesh 答案非常相似,但采用了更通用的方法。
您可以按如下方式声明双精度数组:
var myDoubleArray = [[]];
以及以下列方式存储和访问内容:
var testArray1 = [9,8]
var testArray2 = [3,5,7,9,10]
var testArray3 = {"test":123}
var index = 0;
myDoubleArray[index++] = testArray1;
myDoubleArray[index++] = testArray2;
myDoubleArray[index++] = testArray3;
console.log(myDoubleArray[0],myDoubleArray[1][3], myDoubleArray[2]['test'],)
这将打印预期的输出
[ 9, 8 ] 9 123
我发现下面是最简单的方法:
var array1 = [[]];数组1[0][100] = 5;警报(数组1 [0] [100]);警报(array1.length);警报(array1[0].length);
array1[1][100] = 666;
抛出 Uncaught TypeError: Cannot set property '100' of undefined
array1[1][100] = 666;
之前的第二个,你需要这样做 array1[1] = [];
。
var playList = [ ['我是按我的方式做的','弗兰克辛纳屈'],['尊重','艾瑞莎富兰克林'],['想象','约翰列侬'],['为奔跑而生','布鲁斯Springsteen'],['Louie Louie','The Kingsmen'],['Maybellene','Chuck Berry']];功能打印(消息){文档。写(消息); } 功能 printSongs( 歌曲 ) { var listHTML; listHTML = '
ES6+、ES2015+ 可以用更简单的方式做到这一点
创建填充为 true 的 3 x 2 数组
[...Array(3)].map(item => Array(2).fill(true))
我必须制作一个灵活的数组函数来根据需要向其中添加“记录”,并且能够在将其发送到数据库进行进一步处理之前更新它们并进行所需的任何计算。这是代码,希望对您有所帮助:)。
function Add2List(clmn1, clmn2, clmn3) {
aColumns.push(clmn1,clmn2,clmn3); // Creates array with "record"
aLine.splice(aPos, 0,aColumns); // Inserts new "record" at position aPos in main array
aColumns = []; // Resets temporary array
aPos++ // Increments position not to overlap previous "records"
}
随意优化和/或指出任何错误:)
aLine.push([clmn1, clmn2, clmn3]);
怎么样?
Javascript 不支持二维数组,相反,我们将一个数组存储在另一个数组中,并根据您要访问的数组的位置从该数组中获取数据。记住数组编号从零开始。
代码示例:
/* Two dimensional array that's 5 x 5
C0 C1 C2 C3 C4
R0[1][1][1][1][1]
R1[1][1][1][1][1]
R2[1][1][1][1][1]
R3[1][1][1][1][1]
R4[1][1][1][1][1]
*/
var row0 = [1,1,1,1,1],
row1 = [1,1,1,1,1],
row2 = [1,1,1,1,1],
row3 = [1,1,1,1,1],
row4 = [1,1,1,1,1];
var table = [row0,row1,row2,row3,row4];
console.log(table[0][0]); // Get the first item in the array
这是我发现制作二维数组的快速方法。
function createArray(x, y) {
return Array.apply(null, Array(x)).map(e => Array(y));
}
您也可以轻松地将这个函数转换为 ES5 函数。
function createArray(x, y) {
return Array.apply(null, Array(x)).map(function(e) {
return Array(y);
});
}
为什么会这样:new Array(n)
构造函数创建一个原型为 Array.prototype
的对象,然后分配该对象的 length
,从而产生一个未填充的数组。由于缺少实际成员,我们无法在其上运行 Array.prototype.map
函数。
但是,当您向构造函数提供多个参数时,例如当您执行 Array(1, 2, 3, 4)
时,构造函数将使用 arguments
对象来正确实例化和填充 Array
对象。
出于这个原因,我们可以使用 Array.apply(null, Array(x))
,因为 apply
函数会将参数传播到构造函数中。为澄清起见,执行 Array.apply(null, Array(3))
等同于执行 Array(null, null, null)
。
现在我们已经创建了一个实际填充的数组,我们需要做的就是调用 map
并创建第二层 (y
)。
一个创建填充为 0 的 am*n 二维数组的衬垫。
new Array(m).fill(new Array(n).fill(0));
a = Array(m).fill(0).map(() => Array(n).fill(0))
? map
将解开引用并为每个插槽创建唯一的数组。
jagged array
(数组数组) - JavaScript 是否像其他一些语言一样在jagged
和多维之间有区别?