【问题标题】:Array.fill(Array) creates copies by references not by value [duplicate]Array.fill(Array) 通过引用而不是值创建副本 [重复]
【发布时间】:2023-01-30 20:57:49
【问题描述】:

我正在尝试使用 Array.fill 创建一个 6 x 12 矩阵

let m = Array(6).fill(Array(12).fill(0));

虽然这有效,但问题是内部数组实际上都引用同一个 Array 对象。

let m = Array(6).fill(Array(12).fill(0));
m[0][0] = 1;
console.log(m[1][0]); // Outputs 1 instead of 0

我希望(并期望)m[1][0] 的值为0

我如何强制Array.fill 填充给定参数的按值复制(例如:Array(12).fill(0) 是我的参数)而不是按引用复制?

【问题讨论】:

  • 你不能强迫Array.fill()做它已经做的以外的任何事情。您当然可以编写自己的函数来执行此操作。
  • @Pointy 你是对的,填充“深层复制”的第二个参数会很有用:)
  • 能够传递某种生成器函数可能会很好。
  • 使用 lodashes 深度克隆,它会删除引用
  • @WilliamKunkel:在大多数用例中,您可以简单地执行 Array.from(generator) 而不是 Array(6).fillBy(generator, 0, 6)

标签: javascript reference ecmascript-6


【解决方案1】:

您可以改用 Array.from()

感谢 cmets 中的 Pranav C Balan 提出进一步改进的建议。

let m = Array.from({length: 6}, e => Array(12).fill(0));

m[0][0] = 1;
console.log(m[0][0]); // Expecting 1
console.log(m[0][1]); // Expecting 0
console.log(m[1][0]); // Expecting 0

原始语句(上面更好地优化):

let m = Array.from({length: 6}, e => Array.from({length: 12}, e => 0));

【讨论】:

  • let m = Array.from({length: 6}, e => Array(12).fill(0));
【解决方案2】:

你不能用.fill()来做,但是你可以用.map()

let m = new Array(6).map(function() { return new Array(12); });

编辑哦,等等,那行不通; .map() 不会遍历未初始化的元素。你可以先填写它:

let m = new Array(6).fill(null).map(function() { return new Array(12); });

【讨论】:

  • new Array(6).fill().map(...?使用箭头函数,它实际上看起来不错。
  • 你可以做[...Array(6)].map(() => Array(12).fill(0))
  • 不过,这将创建一个新数组,而不是就地改变它。
  • 你们这些拥有新语言功能的孩子需要离开我的草坪
  • @Pointy:我认为Array.from(Array(6)).map(…) 比那个丑陋的传播运算符更具可读性:-)
【解决方案3】:

你不能这样做Array#fill方法。而是遍历数组并使用 for 循环添加新创建的数组。

let m = Array(6);
for (var i = 0; i < m.length; i++)
  m[i] = Array(12).fill(0)

m[0][0] = 1;
console.log(m[1][0]);

【讨论】:

  • 我知道我可以通过使用循环来创建它,但这是我首先要避免的。 :D
猜你喜欢
  • 2012-11-25
  • 1970-01-01
  • 2018-06-08
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 2012-02-03
  • 1970-01-01
相关资源
最近更新 更多