在克隆的哈希上调用Array#delete_at也会改变原始哈希值?

时间:2013-05-01 18:51:56

标签: ruby arrays hashmap

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

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

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

1 个答案:

答案 0 :(得分:2)

问题是被称为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)

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

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