我一直在网上阅读,一些地方说这是不可能的,一些地方说这是可能的,然后给出一个例子,另一些地方反驳这个例子,等等。

如何在JavaScript中声明一个2维数组?(假设这是可能的) 我如何访问它的成员?(myArray[0][1] or myArray[0,1]?)


当前回答

性能

今天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大数组在所有浏览器上都很慢 解决方案K对于所有浏览器的小数组都很慢 解决方案A,E,G对于所有浏览器的大数组都很慢 对于所有浏览器上的所有数组,解决方案M是最慢的

初始化二维数组的结论

基于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)对于所有浏览器上的大小数组都是最慢的

细节

测试没有填充(初始化)输出数组的解决方案

我们测试解的速度

小数组(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 < arrr .length;i++) arr[i] = new Array(c); 返回arr; } 函数C(r, C) { var arr =数组(r); For (var I = 0;I < arrr .length;i++) arr[i] =数组(c); 返回arr; } 函数D(r, c) { //奇怪,但有效 Var arr = []; For (var I = 0;I < r;我+ +){ arr.push ([]); 加勒比海盗[我].push(数组(c)); } 返回arr; } 函数E(r, c) { Let array = [[]]; For (var x = 0;X < c;x + +) { 数组[x] = []; For (var y = 0;Y < r;数组[x][Y] = [0]; } 返回数组; } 函数F(r, c) { var makeArray = function(调暗,arr) { If (dims[1] === undefined) { 返回数组(dim [0]); } arr = Array(dimms [0]); For (var I = 0;I < dim [0];我+ +){ arr[i] = Array(dimms [1]); arr[i] = makeArray(dms .slice(1), arr[i]); } 返回arr; } 返回makeArray([r, c]); } 函数G(r) { Var a = []; While (a.push([]) < r); 返回一个; } 函数H(r,c) { 函数createArray(length) { var arr =新的数组(长度|| 0), I =长度; 如果参数。长度> 1){ var args = Array.prototype.slice。调用(参数,1); while(i——)arr[length-1 - i] = createArray。应用(这个,args); } 返回arr; } 返回createArray (r、c); } 函数I(r, c) { 返回数组(r)[…]。map(x =>数组(c)); } 函数J(r, c) { 返回Array(r).fill(0).map(() => Array(c)); } 函数K(r, c) { return Array.from(Array(r), () => Array(c)); } 函数L(r, c) { 返回Array.from({length: r})。map(e => Array(c)); } 函数M(r, c) { 返回Array.from({长度:r}, () = > Array.from({长度:c }, () => {})); } 函数N(r, c) { 返回{} } // ----------------------------------------------- / /显示 // ----------------------------------------------- Log = (t, f) => { 令A = f(3,4);//创建3行4列的数组 A[1][2] = 6 //第2行第3列设置为6 console.log(“$ {t}[1][2]: ${一个[1][2]},完整:$ {JSON.stringify (A) .replace(/空/ g,“x”)}”); } Log2 = (t, f) => { 令A = f(3,4);//创建3行4列的数组 A[[1,2]] = 6 //第2行第3列设为6 console.log(“$ {t}[1][2]: ${一个[[1,2]]},完整:$ {JSON.stringify (A) .replace(/空/ g,“x”)}”); } 日志(' 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] =数组(c).fill(def); 返回arr; } 函数B(r, c, def) { var arr = new Array(r); For (var I = 0;I < arrr .length;i++) arr[i] = new Array(c).fill(def); 返回arr; } 函数C(r, C, def) { var arr =数组(r); For (var I = 0;I < arrr .length;i++) arr[i] =数组(c).fill(def); 返回arr; } 函数D(r, c, def) { //奇怪,但有效 Var arr = []; For (var I = 0;I < r;我+ +){ arr.push ([]); 加勒比海盗[我].push(数组(c)); } For (var I = 0;I < r;i++) for (var j = 0;J < c;j + +) arr[我][j] = def 返回arr; } 函数E(r, c, def) { Let array = [[]]; For (var x = 0;X < c;x + +) { 数组[x] = []; For (var y = 0;Y < r;数组[x][Y] = def; } 返回数组; } 函数F(r, c, def) { var makeArray = function(调暗,arr) { If (dims[1] === undefined) { 返回数组(退去[0]).fill (def); } arr = Array(dimms [0]); For (var I = 0;I < dim [0];我+ +){ arr[i] = Array(dimms [1]); arr[i] = makeArray(dms .slice(1), arr[i]); } 返回arr; } 返回makeArray([r, c]); } 函数G(r, c, def) { Var a = []; while (a.push(Array(c).fill(def)) < r); 返回一个; } 函数H(r,c, def) { 函数createArray(length) { var arr =新的数组(长度|| 0), I =长度; 如果参数。长度> 1){ var args = Array.prototype.slice。调用(参数,1); while(i——)arr[length-1 - i] = createArray。应用(这个,args) .fill (def); } 返回arr; } 返回createArray (r、c); } 函数I(r, c, def) { 返回数组(r)[…]。map(x =>数组(c).fill(def)); } 函数J(r, c, def) { 返回数组(r) .fill (0) . map(() = >数组(c) .fill (def)); } 函数K(r, c, def) { 返回Array.from(Array(r), () => Array(c).fill(def)); } 函数L(r, c, def) { 返回Array.from({length: r})。map(e => Array(c).fill(def)); } 函数M(r, c, def) { 返回Array.from({长度:r}, () = > Array.from({长度: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]: ${一个[1][2]},{t}美元[800][901]:${一个[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]: ${一个[[1,2]]},{t}美元[800][900]:${一个[[800900]]}'); } 日志(' 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); 这是解决方案的展示,而不是基准测试

其他回答

如果你想要的是一个4x4矩阵,看看DOMMatrix,它很容易使用,我可以说,

let m = new DOMMatrix(); 
// m.m11, m.m12, m.m13, m.m14, ..., m.m41, m.m42, m.m43, m.m44

最初由于不同的原因,它在node.js上不可用,并且仅限于4x4。

你也可以考虑使用一个自动激活对象,而不是JS的数组,看看我的答案,但这里也带来了更多的说服力:

var tree = () => new Proxy({}, { get: (target, name) => name in target ? target[name] : target[name] = tree() });

var t = tree();
t[0][2][3] = 4;
console.log(t[0][2][3]);

它使用新的JS和行为不正确时,你迭代它,所以要小心它。

如果你需要一个灵活的多维数组生成器,也可以看看这个。

实际上呢?是的。你可以创建一个数组的数组,作为一个2D数组,因为每个项目本身就是一个数组: Let items = [ (1、2), (3、4), (5、6) ]; console.log(项目[0][0]);/ / 1 console.log(项目[0][1]);/ / 2 console.log(项目[1][0]);/ / 3 console.log(项目[1][1]);/ / 4 console.log(项目);

但从技术上讲,这只是一个数组的数组,而不是一个“真正的”2D数组,正如I. J. Kennedy指出的那样。

需要注意的是,您可以将数组嵌套到另一个数组中,从而创建“多维”数组。

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

对于一行程序爱好者来说

// 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+扩展操作符(“受InspiredJW启发”:))

// same as above just a little shorter
const arr2d = [...Array(8)].map(() => Array(8).fill("0"))

这并不是一个真正的答案,但也许根本就不要使用多维数组。你可以很容易地做一个更大的一维数组,并将索引器相乘,并通过该值进行索引!在我看来,那里更干净。