【问题标题】:Declare an empty two-dimensional array in Javascript?在Javascript中声明一个空的二维数组?
【发布时间】:2013-08-12 08:41:41
【问题描述】:

我想在 Javascript 中创建一个二维数组,我将在其中存储坐标 (x,y)。我还不知道我会有多少对坐标,因为它们是由用户输入动态生成的。

预定义二维数组示例:

var Arr=[[1,2],[3,4],[5,6]];

我想我可以使用 PUSH 方法在数组末尾添加一条新记录。

如何声明一个空的二维数组,这样当我使用我的第一个 Arr.push() 时,它将被添加到索引 0,并且通过 push 写入的每条下一条记录都将采用下一个索引?

这可能很容易做到,我只是 JS 的新手,如果有人可以编写一个简短的工作代码 sn-p 供我检查,我将不胜感激。谢谢

【问题讨论】:

  • 你试过var Arr = new Array(new Array());吗?是的,pushpop 在数组末尾添加或删除元素,而shiftunshift 在数组开头删除或添加元素。
  • 这听起来像是两个不同的问题。首先,您想要任意大小的数组。然后你有点问一个涉及推送方法的不同问题。 (另外,如果你想回答你自己的问题,我认为最好在答案部分这样做。)这是谷歌中排名靠前的问题,用于在 JavaScript 中创建多维数组,我知道谷歌没有在这里决定内容,但我想说这是一个根本性重要的问题,有很多古怪的答案。

标签: javascript arrays dynamic 2d push


【解决方案1】:

你可以像这样声明一个常规数组:

var arry = [];

那么当你有一对值要添加到数组中时,你需要做的就是:

arry.push([value_1, value2]);

是的,第一次调用 arry.push 时,这对值将被放置在索引 0 处。

来自nodejs repl:

> var arry = [];
undefined
> arry.push([1,2]);
1
> arry
[ [ 1, 2 ] ]
> arry.push([2,3]);
2
> arry
[ [ 1, 2 ], [ 2, 3 ] ]

当然,由于 javascript 是动态类型的,因此不会有类型检查器强制数组保持二维。您必须确保只添加坐标对,而不是执行以下操作:

> arry.push(100);
3
> arry
[ [ 1, 2 ],
  [ 2, 3 ],
  100 ]

【讨论】:

  • 这似乎是一个优雅的解决方案,所以我得到了 X 和 Y 坐标,并像这样插入它们:arry.push([x,y]); - 但是我以后如何返回,例如索引 0 上的 x 坐标?
  • 您可以只检索 arry[0][0]。 (并且要获得 Y 坐标,您可以检索 arry[0][1]。)
【解决方案2】:

如果要随创建一起初始化,可以使用fillmap

const matrix = new Array(5).fill(0).map(() => new Array(4).fill(0));

5 是行数,4 是列数。

【讨论】:

  • 这在声明性上下文中也很有效,例如将二维数组预分配为对象成员。也许不是从头开始设计的东西,但对于从其他语言移植等任务很有用。
  • 请注意这里map(() => {})是用来创建独立行的,是必须的。 new Array(5).fill(new Array(4).fill(0))的方式是非常危险的举动。由于所有行都填充了对 ONE 数组的引用,因此如果您更新 arr[0][0]arr[1][0] 的值也会更改。当您将此数组用作缓存表时,这可能会引发非常严重和黑暗的问题。
  • @Kaihua 我是 JavaScript 新手,但使用了下面由 Kamil Kiełczewski 提供的打印格式代码,Abhinav 的解决方案没有问题。如果修改了任何元素,则对任何其他元素都没有 更改。我想您的评论类似于 Python 中的浅拷贝,但这里并非如此。
  • @Kaihua,我不明白,这个引用同一个数组是怎么回事。如果您创建 5 个元素的数组 (new Array(5)) 并用新创建的数组 (new Array(4)) 填充它?! new Array() 不是意味着您不再创建新数组了吗?! JS怎么了?!
  • @RamzanChasygov 语言可能不完美,具体取决于上下文 =D
【解决方案3】:

ES6

矩阵 m 大小为 3 行 5 列(删除 .fill(0) 以不以零初始化)

[...Array(3)].map(x=>Array(5).fill(0))       

let Array2D = (r,c) => [...Array(r)].map(x=>Array(c).fill(0));

let m = Array2D(3,5);

m[1][0] = 2;  // second row, first column
m[2][4] = 8;  // last row, last column

// print formated array
console.log(JSON.stringify(m)
  .replace(/(\[\[)(.*)(\]\])/g,'[\n  [$2]\n]').replace(/],/g,'],\n  ')
);

【讨论】:

  • @AndrewBenjamin - 问题到底出在哪里 - 你能描述一下或提供测试用例吗?
  • 好吧,我复制了您的代码,当我尝试随机访问数组中的值时,它抛出了错误。然而,一个小小的修改就奏效了: Array(n + 1).fill(Array(m+1).fill(0))
  • 既然你把我送到了正确的方向,我喜欢你的风格......赞成......虽然不知道为什么你按原样编写代码对我来说不太适合。忽略打字稿铸造,唯一的修改是“填充”而不是“地图”
  • 我想我知道出了什么问题,我在复制粘贴脚本后不小心将第一个数组转换为 而不是 。所以我的错。
【解决方案4】:

如果您希望能够像这样访问矩阵 矩阵[i][j]

我觉得循环初始化最方便。

var matrix = [],
    cols = 3;

//init the grid matrix
for ( var i = 0; i < cols; i++ ) {
    matrix[i] = []; 
}

这会给你 [[],[],[]]

所以 矩阵[0][0] 矩阵[1][0] 返回 undefined 而不是错误“Uncaught TypeError: Cannot set property '0' of undefined”

【讨论】:

    【解决方案5】:

    您可以使用速记语法将一个数组嵌套在另一个数组中:

       var twoDee = [[]];
    

    【讨论】:

      【解决方案6】:

      你可以试试这样的:-

      var arr = new Array([]);
      

      推送数据:

      arr[0][0] = 'abc xyz';
      

      【讨论】:

      • arr[1][0]=3 => Uncaught TypeError: Cannot set property '0' of undefined
      【解决方案7】:

      空数组是通过省略值来定义的,如下所示:

      v=[[],[]]
      a=[]
      b=[1,2]
      a.push(b)
      b==a[0]
      

      【讨论】:

        【解决方案8】:

        您可以使用函数用数组填充数组:

        
        
        
        var arr = [];
        var rows = 11;
        var columns = 12;
        
        fill2DimensionsArray(arr, rows, columns);
        
        function fill2DimensionsArray(arr, rows, columns){
            for (var i = 0; i < rows; i++) {
                arr.push([0])
                for (var j = 0; j < columns; j++) {
                    arr[i][j] = 0;
                }
            }
        }
        

        结果是:

        
        
        
        Array(11)
        0:(12) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        1:(12) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        2:(12) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        3:(12) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        4:(12) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        5:(12) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        6:(12) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        7:(12) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        8:(12) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        9:(12) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        10:(12)[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        

        【讨论】:

          【解决方案9】:

          我知道这是一个旧线程,但我建议使用array of objects 而不是array of arrays。我认为它使代码更易于理解和更新。

          // Use meaningful variable names like 'points', 
          // anything better than a bad pirate joke, 'arr'!
          var points = [];
          
          // Create an object literal, then add it to the array
          var point = {x: 0, y: 0};
          points.push(point);
          
          // Create and add the object to the array in 1 line
          points.push({x:5, y:5});
          
          // Create the object from local variables 
          var x = 10;
          var y = 8;
          points.push({x, y});
          
          // Ask the user for a point too
          var response = prompt("Please enter a coordinate point. Example: 3,8");
          var coords = response.split(",").map(Number);
          points.push({x: coords[0], y: coords[1]});
          
          // Show the results
          var canvas = document.getElementById('graph');
          var painter = canvas.getContext("2d");
          var width = canvas.width, height = canvas.height;
          var scale = 10, radius = 3.5, deg0 = 0, deg360 = 2 * Math.PI;
          
          painter.beginPath();
          for (var point of points) {
              var x = point.x * scale + scale;
              var y = height - point.y * scale - scale;
              painter.moveTo(x + radius, y);
              painter.arc(x, y, radius, deg0, deg360);
              painter.fillText(`${point.x}, ${point.y}`, x + radius + 1, y + radius + 1);
          }
          painter.stroke();
          &lt;canvas id="graph" width="150" height="150" style="border: 1px solid red;"&gt;&lt;/canvas&gt;

          【讨论】:

            【解决方案10】:

            一个班轮

            let m = 3 // rows
            let n = 3 // columns
            let array2D = Array(m).fill().map(entry => Array(n))
            

            此实现为每个条目创建一个唯一的子数组。所以设置array2D[0][1] = 'm'不会将每个条目的[1]索引设置为'm'

            【讨论】:

            • 让 array2D = Array(3).fill().map(entry => Array(3)) 合二为一
            【解决方案11】:
            const grid = Array.from(Array(3), e => Array(4));
            

            Array.from(arrayLike, mapfn)

            调用mapfn,传入undefined,返回new Array(4)

            创建一个迭代器并重复调用next 值。从nextnext().value 返回的值为undefined。然后将这个值undefined 传递给新创建的数组的迭代器。每次迭代的value都是undefined,你记录一下就可以看到。

            var grid2 = Array.from(Array(3), e => {
              console.log(e); // undefined
              return Array(4); // a new Array.
            });
            

            【讨论】:

            • 请添加一些描述如何以及为什么它工作。您的回答应该能让其他用户学习。
            • 如果您想将数组初始化为特定值,例如 0:const grid = Array.from(Array(3), () =&gt; Array(4).fill(0))
            【解决方案12】:

            创建一个对象并将该对象推入一个数组

             var jSONdataHolder = function(country, lat, lon) {
            
                this.country = country;
                this.lat = lat;
                this.lon = lon;
            }
            
            var jSONholderArr = [];
            
            jSONholderArr.push(new jSONdataHolder("Sweden", "60", "17"));
            jSONholderArr.push(new jSONdataHolder("Portugal", "38", "9"));
            jSONholderArr.push(new jSONdataHolder("Brazil", "23", "-46"));
            
            var nObj = jSONholderArr.length;
            for (var i = 0; i < nObj; i++) {
               console.log(jSONholderArr[i].country + "; " + jSONholderArr[i].lat + "; " + 
               jSONholderArr[i].lon);
            
            }
            

            【讨论】:

              【解决方案13】:

              var arr = [];
              var rows = 3;
              var columns = 2;
              
              for (var i = 0; i < rows; i++) {
                  arr.push([]); // creates arrays in arr
              }
              console.log('elements of arr are arrays:');
              console.log(arr);
              
              for (var i = 0; i < rows; i++) {
                  for (var j = 0; j < columns; j++) {
                      arr[i][j] = null; // empty 2D array: it doesn't make much sense to do this
                  }
              }
              console.log();
              console.log('empty 2D array:');
              console.log(arr);
              
              for (var i = 0; i < rows; i++) {
                  for (var j = 0; j < columns; j++) {
                      arr[i][j] = columns * i + j + 1;
                  }
              }
              console.log();
              console.log('2D array filled with values:');
              console.log(arr);

              【讨论】:

                【解决方案14】:

                如果我们不使用 ES2015 并且没有 fill(),就使用 .apply()

                https://stackoverflow.com/a/47041157/1851492

                let Array2D = (r, c, fill) => Array.apply(null, new Array(r)).map(function() {return Array.apply(null, new Array(c)).map(function() {return fill})})
                
                console.log(JSON.stringify(Array2D(3,4,0)));
                console.log(JSON.stringify(Array2D(4,5,1)));

                【讨论】:

                  【解决方案15】:

                  没必要这么麻烦!很简单

                  这将创建 2 * 3 的字符串矩阵。

                  var array=[];
                  var x = 2, y = 3;
                  var s = 'abcdefg';
                  
                  for(var i = 0; i<x; i++){
                      array[i]=new Array();
                        for(var j = 0; j<y; j++){
                           array[i].push(s.charAt(counter++));
                          }
                      }
                  

                  【讨论】:

                    【解决方案16】:

                    怎么了

                    var arr2 = new Array(10,20);
                        arr2[0,0] = 5;
                        arr2[0,1] = 2
                        console.log("sum is   " + (arr2[0,0] +  arr2[0,1]))
                    

                    应该读出“sum is 7”

                    【讨论】:

                    • 现在设置arr2[1,0]=4console.log("sum is " + (arr2[0,0] + arr2[0,1])) 然后给出“总和为 6”。您并没有真正创建一个二维数组,而是一个包含条目“10”和“20”的简单数组。当您尝试使用逗号分隔的 indizes 访问条目时,您真正要做的是在这里描述:stackoverflow.com/questions/7421013/…
                    【解决方案17】:

                    我们通常知道列数,但可能不知道行数(记录)。这是我的解决方案的一个示例,它利用了上述大部分内容。 (对于那些在 JS 方面比我更有经验的人 - 几乎所有人 - 欢迎任何代码改进建议)

                         var a_cols = [null,null,null,null,null,null,null,null,null];
                         var a_rxc  = [[a_cols]];
                    
                         // just checking  var arr =  a_rxc.length ; //Array.isArray(a_rxc);
                         // alert ("a_rxc length=" + arr) ; Returned 1 
                         /* Quick test of array to check can assign new rows to a_rxc. 
                            i can be treated as the rows dimension and  j the columns*/
                           for (i=0; i<3; i++) {
                              for (j=0; j<9; j++) {
                                a_rxc[i][j] = i*j;
                                alert ("i=" + i + "j=" + j + "  "  + a_rxc[i][j] );
                               }
                              if (i+1<3) { a_rxc[i+1] = [[a_cols]]; }
                            }
                    

                    如果将此数组传递给服务器,那么适合我的 ajax 是

                     $.post("../ajax/myservercode.php",
                           {
                            jqArrArg1 : a_onedimarray,
                            jqArrArg2 : a_rxc
                           },
                           function(){  },"text" )
                            .done(function(srvresp,status) { $("#id_PageContainer").html(srvresp);} ) 
                            .fail(function(jqXHR,status) { alert("jqXHR AJAX error " + jqXHR + ">>" + status );} );
                    

                    【讨论】:

                      【解决方案18】:

                      您可以在填充第一个数组时嵌套一个新数组:

                      let ROWS = 2,
                          COLS = 6;
                      let arr = new Array(ROWS).fill(new Array(COLS).fill(-1));
                      
                      Output:
                      arr = 
                      [
                        [-1, -1, -1, -1, -1, -1],
                        [-1, -1, -1, -1, -1, -1]
                      ]
                      

                      如果您感到困惑,让我们通过声明/填充 1 个数组来分解: 新建一个大小为 d 的数组,填充任意初始值

                      let arr1d = new Array(d).fill(&lt;whatever_fill_val&gt;);

                      现在,您可以用另一个数组来填充它,而不是用 int/string/etc 填充您的第一个数组,就像您填充嵌套的数组一样!

                      let arr = new Array(d).fill(new Array(n).fill(-1));

                      【讨论】:

                      • 正如@MrMartiniMo 在类似答案中指出的那样:此解决方案的问题是每一行都包含相同的数组。如果你设置arr[1][2] = 1 每行将包含[-1, -1, 1, -1]
                      【解决方案19】:

                      // 对于 3 x 5 数组

                      new Array(3).fill(new Array(5).fill(0))
                      

                      【讨论】:

                      • 不起作用。第一维中的每个项目都包含对同一辅助数组的引用。所以 a[0][y] === a[1][y] === a[2][y] 保证你得到一些奇怪的结果。
                      猜你喜欢
                      • 1970-01-01
                      • 2022-01-15
                      • 2010-12-21
                      • 1970-01-01
                      • 2012-02-27
                      • 2018-06-29
                      • 1970-01-01
                      • 2012-04-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多