likes
comments
collection
share

JavaScript如何定义一个真正的二维数组

作者站长头像
站长
· 阅读数 51

最近做了一道京东2022秋招的算法题,题目需要输出的数据格式是二维数组。但在ac的时候我的答案出现了问题,二维数组中每一个子数组中的值都是一样的。当时我一直深陷在从两层for循环中寻找bug,却忽视了问题是出现在我定义二维数组的方式上,因此这里我要仔细说一下如何定义一个真正的二维数组

首先来看一个例子,目前网上最多的用来定义二维数组的方法

const n = 3
let arr = new Array(n).fill(new Array(n).fill(0));
console.log(arr)

JavaScript如何定义一个真正的二维数组

看起来似乎是对了,数组里面嵌套了三个数组,和我们想象的二维数组的样子相同,但问题就在这里。 看起来对的难道真的就对了么。我们来进行一个操作 给二维数组里的元素赋值

arr[0][1] = 1;
console.log("赋值后", arr);

JavaScript如何定义一个真正的二维数组

卧槽!什么情况我明明只给二维数组的第0行第1列赋值了1啊,怎么每一个的第一列都变成1了 相信很多人第一次遇到这种情况都会发出和我一样的疑惑,那问题出在哪里呢。

问题所在Array.fill()

不熟悉的朋友可以看一下MDN上对其简单的解释 # Array.prototype.fill()

我希望大家注意到其中这么一句话: “当一个对象被传递给 fill 方法的时候,填充数组的是这个对象的引用。”

注意:如果填充的内容为'object'类型,那么被赋值的是同一个内存地址的对象,而不是深拷贝的对象。

这就解释了上面的问题。我们根据内存地址找到对象,对这个对象本身进行了修改。这样其他的子数组也就发什了改变因为这些子数组都是从同一个内存地址来拿的。因此通过上述方法定义的二维数组 并不能称作一个真正的二维数组 (这里我说的对象其实是js中的引用类型数据,数组,对象,map, Set这些都是。)

如何定义一个真正的二维数组呢

其实很简单,两层for循环就能完成

let arr1 = new Array(n);
for (let i = 0; i < n; i++) {
  for (let j = 0; j < n; j++) {
    arr1[i] = new Array(n).fill(0);
  }
}

让我们对其赋值,然后看一下前后的结果

console.log("赋值前", arr1);
arr1[0][1] = 1;
console.log("赋值后", arr1);

JavaScript如何定义一个真正的二维数组

这下对了我们定义了一个真正的二维数组

希望以后在遇到二维数组的题时 大家放弃第一种写法,我们需要的是一个真正的二维数组。

转载自:https://juejin.cn/post/7136799319130112007
评论
请登录