【问题标题】:Calling Array#delete_at on a cloned hash changes the original hash too?在克隆的哈希上调用 Array#delete_at 也会改变原始哈希?
【发布时间】:2013-05-01 18:51:55
【问题描述】:

我遇到了一个奇怪的问题,如果我尝试在克隆的哈希上调用delete_at,它恰好有一个数组作为它的键值之一,它也会从原始哈希中删除。有没有办法解决这个问题?

h1 = {:stuff => [1,2,3]}
h2 = h1.clone
h2[:stuff].delete_at(0)

puts h1 #=> {:stuff=>[2, 3]}
puts h2 #=> {:stuff=>[2, 3]}

【问题讨论】:

  • 为了更清楚起见,我在 irb 中做了这个,两个数组都有相同的object_id

标签: ruby arrays hashmap


【解决方案1】:

问题在于称为h2[:stuff] 的数组与h1[:stuff] 相同。你需要dup那个。

h1 = {:stuff => [1,2,3]}
h2 = h1.clone
h2.keys.each{|k| h2[k] = h2[k].dup}
h2[:stuff].delete_at(0)

或者,更直接地说,

h1 = {:stuff => [1,2,3]}
h2 = {}
h1.each{|k, v| h2[k] = v.dup}
h2[:stuff].delete_at(0)

请注意,不可变对象不能是duped。在这种情况下,您需要执行以下操作:

h1 = {:stuff => [1,2,3]}
h2 = {}
h1.each{|k, v| h2[k] = v.dup rescue v}
h2[:stuff].delete_at(0)

【讨论】:

  • 这是因为clone 做了浅拷贝吗?
猜你喜欢
  • 2012-11-24
  • 2011-02-07
  • 2019-10-28
  • 2012-07-07
  • 2013-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多