动态创建数组
#javascript #数组

原因

在最近的算法挑战中,我想创建一个可欣赏到数据分组的十个“存储桶”的集合。在实践中,这意味着创建一系列数组,例如:

[[], [], [], [], [], [], [], [], [], []]

什么没有奏效

我想动态创建每个数组,而不是硬码。我的第一次尝试(从内存和MDN文档的粗略浏览中)是使用数组构造函数与链接的.fill方法:

const arr = new Array(10).fill([]);
console.log(arr);
// => [[], [], [], [], [], [], [], [], [], []];

乍一看,这似乎有效。记录我的新arr的控制台显示了一个包含10个空数组的数组,因此我继续求解该算法。

我很快就开始填充内部阵列(水桶)时,我注意到存在问题 - 例如,在一个“桶”中添加一个元素,例如在索引5上,更新每个存储桶以匹配,而不是仅仅是预期的水桶:

arr[5].push("hello");
console.log(arr);
// => [["hello"], ["hello"], ["hello"], ["hello"], ["hello"], ["hello"], ["hello"], ["hello"], ["hello"], ["hello"]];

返回koude2的MDN文档,问题很清楚:

Screenshot of MDN docs for fill method

由于数组是一种对象,我的每个数组桶实际上都在内存中引用相同的对象。因此,我的数组没有创建10个不同的阵列,而只是显示同一数组的10份。

Array.from进行营救

要动态创建数组数组(或其他对象),您可以使用.from方法:

const newArr = Array.from({ length: 10 }, () => []);
console.log(newArr);
// => [[], [], [], [], [], [], [], [], [], []];

这里的{length: 10}是“阵列”。由于鸭子的效果,可以使用该长度属性(请参阅here的出色堆栈溢出说明)。 () => []是“ mapfn”,其返回值用于填充数组。

现在,将元素推到索引5上的数组,仅更新该数组,如预期:

newArr[5].push("hello");
console.log(newArr);
// => [[], [], [], [], [], ["hello"], [], [], [], []];