原因
在最近的算法挑战中,我想创建一个可欣赏到数据分组的十个“存储桶”的集合。在实践中,这意味着创建一系列数组,例如:
[[], [], [], [], [], [], [], [], [], []]
什么没有奏效
我想动态创建每个数组,而不是硬码。我的第一次尝试(从内存和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文档,问题很清楚:
由于数组是一种对象,我的每个数组桶实际上都在内存中引用相同的对象。因此,我的数组没有创建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"], [], [], [], []];