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

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


当前回答

这是我的多维数组的实现。

在这种方法中,我创建了一个一维数组

我已经添加了一个原型函数多数组对象,它可以用来创建任何维度的数组。

我还为数组对象添加了一个原型函数索引,用于从多维索引中获取线性数组的索引。

创建Array

//Equivalent to arr[I][J][K]..[] in C
var arr = new Array().multi(I,J,K,..);

在任意索引处访问数组值

//Equivalent in C arr[i][j][k];
var vaue = arr[arr.index(i,j,k)];

片段

/* 存储数组为一维 使用Array.index(i,j,k,…) * / Array.prototype.multi = function(){ 这一点。Multi_size =参数; 这一点。Multi_len = 1 对于(参数的关键字)这个。Multi_len *= parameters [key]; (var i=0;i<this.multi_len;i++) this.push(0); 返回; } Array.prototype.index = function(){ Var _size = this.multi_len; Var temp = 1; Var指数= 0; 对于(参数中的关键字){ 临时* = this.multi_size(例子); 索引+ =(参数(例子)* (_size / temp)) } 返回索引; } //现在你可以使用多维数组 //一个3x3 2D矩阵 var ar2d = new Array().multi(3,3);//一个2D数组 Arr2d [Arr2d .index(1,1,1)] = 5; console.log (arr2d [arr2d.index (1 1 1)]); //一个3x3x3 3D矩阵 var arr3d = new Array().multi(3,3,3);//一个3D数组 Arr3d [Arr3d .index(1,1,1)] = 5; console.log (arr3d [arr3d.index (1 1 1)]); //一个4x3x3 4D矩阵 var arr4d = new Array().multi(4,3,3,3);//一个4D数组 Arr4d [Arr4d .index(4,0,0,1)] = 5; console.log (arr4d [arr4d.index (4 0 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); 这是解决方案的展示,而不是基准测试

下面的例子定义了一个名为activities的二维数组:

    let activities = [
        ['Work', 9],
        ['Eat', 1],
        ['Commute', 2],
        ['Play Game', 1],
        ['Sleep', 7]
    ];

在活动数组中,第一个维度表示活动,第二个维度显示每个活动每天花费的小时数。

要在控制台中显示活动数组,可以使用console.table()方法,如下所示:

console.table(activities);

输出如下所示:

┌─────────┬─────────────┬───┐ │(index)│0│1│ ├─────────┼─────────────┼───┤ │0│’Work’│9│ │1│’Eat’│1│ │2│’Commute’│2│ │3│’Play Game’│1│ │4│’Sleep’│7│ └─────────┴─────────────┴───┘

注意,(index)列用于表示内部数组的索引。

要访问多维数组的元素,首先使用方括号访问返回内部数组的外部数组的元素;然后使用另一个方括号访问内部数组的元素。

下面的例子返回上面activity数组中第一个内部数组的第二个元素:

console.log(activities[0][1]); // 9

向JavaScript多维数组中添加元素

您可以使用数组方法,如push()和splice()来操作多维数组的元素。

例如,要在多维数组的末尾添加一个新元素,可以使用push()方法,如下所示:

activities.push(['Study',2]);

┌─────────┬─────────────┬───┐ │(index)│0│1│ ├─────────┼─────────────┼───┤ │0│’Work’│9│ │1│’Eat’│1│ │2│’Commute’│2│ │3│’Play Game’│1│ │4│’Sleep’│7│ │5│’Study’│2│ └─────────┴─────────────┴───┘

要在数组中间插入一个元素,可以使用splice()方法。下面的代码将一个元素插入到activities数组的第二个位置:

activities.splice(1, 0, ['Programming', 2]);

┌─────────┬───────────────┬───┐ │(index)│0│1│ ├─────────┼───────────────┼───┤ │0│’Work’│9│ │1│’Programming’│2│ │2│’Eat’│1│ │3│’Commute’│2│ │4│’Play Game’│1│ │5│’Sleep’│7│ │6│’Study’│2│ └─────────┴───────────────┴───┘

这个示例计算在每个活动上花费的时间的百分比,并将该百分比附加到内部数组。

activities.forEach(activity => {
    let percentage = ((activity[1] / 24) * 100).toFixed();
    activity[2] = percentage + '%';
});

┌─────────┬───────────────┬───┬───────┐ │(index)│0│1│2│ ├─────────┼───────────────┼───┼───────┤ │0│’Work’│9│’38%’│ │1│’Programming’│2│’8%’│ │2│’Eat’│1│’4%’│ │3│’Commute’│2│’8%’│ │4│’Play Game’│1│’4%’│ │5│’Sleep’│7│’29%’│ │6│’Study’│2│’8%’│ └─────────┴───────────────┴───┴───────┘

从JavaScript多维数组中删除元素

要从数组中删除一个元素,可以使用pop()或splice()方法。

例如,下面的语句删除了activities数组的最后一个元素:

activities.pop();

┌─────────┬───────────────┬───┬───────┐ │(index)│0│1│2│ ├─────────┼───────────────┼───┼───────┤ │0│’Work’│9│’38%’│ │1│’Programming’│2│’8%’│ │2│’Eat’│1│’4%’│ │3│’Commute’│2│’8%’│ │4│’Play Game’│1│’4%’│ │5│’Sleep’│7│’29%’│ └─────────┴───────────────┴───┴───────┘

类似地,可以使用pop()方法从多维数组的内部数组中删除元素。下面的示例从活动数组的内部数组中删除百分比元素。

activities.forEach((activity) => {
    activity.pop(2);
});

┌─────────┬───────────────┬───┐ │(index)│0│1│ ├─────────┼───────────────┼───┤ │0│’Work’│9│ │1│’Programming’│2│ │2│’Eat’│1│ │3│’Commute’│2│ │4│’Play Game’│1│ │5│’Sleep’│7│ └─────────┴───────────────┴───┘

遍历JavaScript多维数组的元素

要迭代多维数组,可以使用嵌套for循环,如下例所示。

// loop the outer array

for (let i = 0; i < activities.length; i++) {
    // get the size of the inner array
    var innerArrayLength = activities[i].length;
    // loop the inner array
    for (let j = 0; j < innerArrayLength; j++) {
        console.log('[' + i + ',' + j + '] = ' + activities[i][j]);
    }
}

第一个循环遍历外部数组的元素,嵌套循环遍历内部数组的元素。

脚本在控制台中输出如下:

[0,0] =功 [0,1] = 9 [1,0] =吃 [1,1] = 1 [2,0] =通勤 [2,1] = 2 [3,0] =玩游戏 [3,1] = 1 [4,0] =睡眠 [4,1] = 7 [5,0] =学习 [5,1] = 2

或者你可以使用forEach()方法两次:

activities.forEach((activity) => {
    activity.forEach((data) => {
        console.log(data);
    });
});

工作 9 吃 1 上下班 2 玩游戏 1 睡眠 7 研究 2

实际上呢?是的。你可以创建一个数组的数组,作为一个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 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],
         ]
*/

更多示例和文档可以在这里找到。

请注意,这还不是一个标准功能。

二维数组的创建方式与一维数组相同。你像数组[0][1]一样访问它们。

var arr = [1, 2, [3, 4], 5];

alert (arr[2][1]); //alerts "4"