【问题标题】:Array.prototype.fill() different from fill as I go [duplicate]Array.prototype.fill() 与 fill 不同 [重复]
【发布时间】:2016-04-19 00:50:19
【问题描述】:

我正在研究一个将其结果输出到二维数组中的问题,并在每个元素中添加一个。

我尽可能简化代码以创建测试用例。如果我按我去填充数组,如下所示:

var a = [[], [], [] ,[] ,[], []];
var d1, d2;
for (d1 = 0; d1 < 6; d1++) {
    for (d2 = 0; d2 < 6; d2++) {
        a[d1][d2] = (a[d1][d2]) ? (a[d1][d2]) + 1 : 1; 
    }
}

我得到一个二维数组,其中所有值都是 1。但是,如果我使用 array.prototype.fill() 预填充数组,如下所示:

var a = new Array(6).fill(new Array(6).fill(0));
var d1, d2;
for (d1 = 0; d1 < 6; d1++) {
    for (d2 = 0; d2 < 6; d2++) {
        a[d1][d2] += 1; 
    }
}

我得到一个充满 6s 的二维数组。即使我用旧的a[d1][d2] = (a[d1][d2]) ? (a[d1][d2]) + 1 : 1; 替换a[d1][d2] += 1,(它应该仍然有效,因为 0 和 undefined 都是假的)我仍然得到 6s。

据我所知,我的代码应该只是循环遍历每个元素并在前一个值上加一个。它不应该多次接触任何元素,所以它们都应该是 1。我是否提前填充数组并不重要。

我理解的失败在哪里?

【问题讨论】:

  • 小测验:new Array(6).fill(new Array(6).fill(0)); 行创建了多少个新数组对象? (提示:它与出现在行中的 new Array 调用的数量相同。)(提示 #2:小于 7 :)。)

标签: javascript arrays


【解决方案1】:

Array.fill 旨在用于用 static 值填充数组中从开始索引到结束索引的所有元素。

不幸的是,这意味着如果你传入一个元素,比如一个新数组,你的数组实际上会被许多对同一个元素的引用填充。换句话说,a 没有填充六个大小为 6 的数组; a 填充有六个指针,指向 同一个数组,大小为 6。

您可以在开发者控制台中轻松验证这一点:

var a = new Array(6).fill(new Array(6).fill(0));
a
>>> [Array[6], Array[6], Array[6], Array[6], Array[6], Array[6]]
a[0]
>>> [0, 0, 0, 0, 0, 0]
a[1]
>>> [0, 0, 0, 0, 0, 0]
a[0][1] = 1
a[0]
>>> [0, 1, 0, 0, 0, 0]
a[1]
>>> [0, 1, 0, 0, 0, 0]

【讨论】:

  • 换句话说(为了 OP 的利益),a[d1] 的每个版本始终是完全相同的数组,因此它的六个值中的每个值都增加了六次。
  • @apsillers Igeddit,Igeddit。 :) 我还没有填写绿色检查,因为我想等一下,以防其他人出现并更简单或更优雅地解释它,或者包括一些我想要的东西......跨度>
  • 你只需要为你的外部数组使用fill以外的东西。我建议mapArray.from
  • 我只是用一个 for 循环完成它,然后继续编写一个递归函数,它可以对任意数量的维度执行此操作,每个维度具有任意数量的元素,以及可选的填充.然后我就一直坚持我以前的填充方法。
猜你喜欢
  • 1970-01-01
  • 2018-05-17
  • 2021-06-28
  • 1970-01-01
  • 1970-01-01
  • 2012-10-30
  • 2018-01-07
相关资源
最近更新 更多