如何在JavaScript中创建空的2d数组?

52

我该如何在Javascript中创建一个空的二维数组(不知道新数组会有多少行或列)?

如果是简单的一维数组,var newArray = new Array(); 我可以为它分配任意数量的元素。但是对于二维数组呢?我能否创建一个不指定行数和列数的二维数组?之后我该如何访问数组元素 (myArray[0][1]myArray[0,1])?


1
重复的内容:https://dev59.com/L2w15IYBdhLWcg3wntKh https://dev59.com/fGsz5IYBdhLWcg3w_NED 等等。 - K_B
我以为 var row_major = Array(height).map(function () { return Array(width); }); 可以解决问题,但今天需要一个二维数组时发现它不行。真是让人沮丧。 - Mark K Cowan
10个回答

105

您可以像这样创建一个6 x 6的空数组:

var myGrid = [...Array(6)].map(e => Array(6));
  • Array(6) 生成一个长度为6且充满undefined值的数组。
  • 我们将该数组映射到另一个充满undefined值的数组。
  • 最终,我们得到一个6x6网格,其中所有位置都是undefined

如果您需要使用默认值初始化该网格:

var value = 'foo'; // by default
var myGrid = [...Array(6)].map(e => Array(6).fill(value));

现在你拥有一个6 x 6的网格,里面装满了'foo'


10
这里有一个被低估的诀窍^^^,适用于任意的2D数组。下面是可重复使用的形式:const create2dArray = (rows, columns) => [...Array(rows).keys()].map(i => Array(columns)) - rkd
3
更多解释会更好 ;) - TOPKAT
5
使用 [...Array(6)] 而不是 Array(6) 的目的是什么? - nog642
5
@nog642,你不能迭代由Array(6)生成的数组,因为它没有元素,但是通过[...Array(6)]生成的数组包含了6个未定义的元素,你可以对它们进行迭代/映射。 - André
2
map 函数中不需要使用 e。你可以使用空括号:.map( () => Array(6).fill(value) - Badrush

38

可以创建一个空的数组,然后向其中添加数据。在JavaScript中,不需要先定义长度。
请查看jsFiddle Live Demo

const arr = [[],[]];

推送数据:

arr[0][2] = 'Hi Mr.A';
arr[1][3] = 'Hi Mr.B';

读取数据:

alert(arr[0][2]);
alert(arr[1][3]);
更新: 这里还有一段由Brady Dowling推荐的视频: 创建一个二维数组:([https://www.youtube.com/watch?v=tMeDkp1J2OM][2])
更新: 这里还有一段由Brady Dowling推荐的视频: 创建一个二维数组:([https://www.youtube.com/watch?v=tMeDkp1J2OM][2])

那么我们如何定义它呢 new Array ()() - meks
@meks 像这样:new Array([]),查看演示。这个答案解决了你的问题吗? - Siamak Motlagh
请参考下面Guffa的答案,进行动态数组的填充。 - Pravinraj Venkatachalam
6
不完全是这样...不是这样。这只能起作用是因为每次赋值时第一个索引会递增。如果您尝试 arr[7][7] = 'Hi Mr.C',则会出现“无法设置属性”的错误。 - den232

14

Javascript中不存在二维数组。

为了实现二维数组的效果,可以使用数组的数组,也称为不规则数组(因为内部数组的长度可以不同)。

创建一个空的不规则数组就像创建任何其他空数组一样:

var myArray = new Array();

您也可以使用一个空数组字面量:

var myArray = [];

要将任何项放入锯齿数组,首先必须将内部数组放入其中,例如像这样:

myArray.push([]);
myArray[0][0] = 'hello';

你也可以创建一个包含一些空数组的数组:

var myArray = [[],[],[]];

这样可以得到一个没有任何项目的锯齿数组,但它已准备好有三个内部数组。

由于它是一个数组的数组,您可以使用myArray[0][1]访问项目。


一个清晰的2D数组概念。 - Pravinraj Venkatachalam

14

假设您想要创建一个100x100的二维数组(即矩阵),您可以通过一行代码完成,如下所示:

var 2darray = new Array(100).fill(null).map(()=>new Array(100).fill(null));

这将创建一个100x100的NULL矩阵。 用您想要的任何维度替换 100 x 100,用您喜欢的默认值或未定义的空白替换 null。


4

您可以使用简单的`for`循环创建一个大致大小的数组,然后在需要时添加更多行。

const arr = [];
const n = 7;
const m = 5;

for (let i = 0; i < n; i++) {
    arr.push(new Array(m).fill(0));
}

const arr = [];
const n = 7;
const m = 5;

for (let i = 0; i < n; i++) {
    arr.push(new Array(m).fill(0));
}

console.log(arr);


3

我使用的函数

function get_empty_2d_array(numRows, numColumnns) {
  return [...Array(numRows)].map(e => Array(numColumnns));
}

function get_2d_array_filled(numRows, numColumnns, fillValue) {
  return [...Array(numRows)].map(e => Array(numColumnns).fill(fillValue));
}

欢迎来到 Stack Overflow。没有任何解释的代码转储很少有帮助。Stack Overflow 是关于学习的,而不是提供盲目复制粘贴的片段。请[编辑]您的问题并解释它如何比 OP 提供的更好。请参见[答案]。 - Chris

2

两件事情:

1)在var myArray = [[],[]];语句之后调用数组长度属性会不正确地报告数组长度。 从技术上讲,由于定义了空数组,它们正在被长度属性计算,但是在长度属性的精神下,它确实应该返回0,因为没有向任何数组添加非空元素。

最小的解决方法是使用两个嵌套的for(in)循环,一个用于第一个数组,一个用于第二个数组,并计算非undefined元素的数量。

2)扩展Siamak A.Motlagh的示例并添加arr([2] [4])= 'Hi Mr.C';分配会失败,并出现“Uncaught TypeError:Cannot set property'4' of undefined”错误。

请参见jsFiddle:http://jsfiddle.net/howardb1/zq8oL2ds/

以下是该代码的副本:

var arr = [[],[]];

alert( arr.length );  // wrong!

var c = 0;
for( var i in arr )
  for( var j in arr[ i ] )
    if( arr[ i ][ j ] != undefined )
      ++c;
alert( c );  // correct

arr[0][2] = 'Hi Mr.A';
alert(arr[0][2]);

arr[1][3] = 'Hi Mr.B';
alert(arr[1][3]);

arr[2][4] = 'Hi Mr.C';  // At this point I'm getting VM558:62 Uncaught TypeError: Cannot set property '4' of undefined
alert(arr[2][4]);

var c = 0;
for( var i in arr )
  for( var j in arr[ i ] )
    if( arr[ i ][ j ] != undefined )
      ++c;
alert( c );

为什么第三个任务失败了?有关[[],[]]创建语句的什么信息表明第一个数组对于0和1是有效的,但对于2不是有效的,或者2和3对于第二个数组是可以的,但对于4不可以?
最重要的是,我如何定义一个数组中包含日期对象的数组,其中第一个和第二个数组都可以容纳日期对象。我使用jQuery-UI DatePicker,它期望一个包含日期对象的日期数组,我已扩展其使用第二个日期数组来包含包含时间的日期对象,以便我可以跟踪多个日期和每天的多个时间。
谢谢。

为什么第三个赋值失败了?创建语句[[],[]]是如何告诉它第一个数组对于0和1有效,但对于2无效,或者第二个数组对于2和3有效,但对于4无效的?这是我的噩梦。 - Mustafa

2
var myArray = [
    ["cats","dogs","monkeys","horses"],
    ["apples","oranges","pears","bananas"]
];
document.write(myArray[0][2]) //returns "monkeys"

0

这也可以作为一个表达式使用:

var twoDarr= new Array(desiredLength);
for (i=0;i<twoDarr.length;i++) {twoDarr[i]=[];} 

关于性能方面,我不知道它与其他答案相比如何。如果你有线索,请在评论中告诉我。

如果您事先不知道数组的长度,请记住可以使用push([])splice(),如果您想要在现有元素的位置上推送/删除/替换新元素。


-1
const grid = new Array(n).fill(new Array(n))

11
所有的内部数组都将具有相同的引用。更改一个内部数组将会更改所有其他内部数组。 在大多数情况下,这不是期望的行为。 - Manish Menaria

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接