将哈希重复复制到独立哈希(浅拷贝)

时间:2017-07-08 16:19:35

标签: ruby

在Ruby中复制哈希的最佳方法是什么,并使其独立于原始哈希?例如:

a = { foo1: "bar1" }
b = a # or b = a.clone / b = a.dup for that matter
b[:foo2] = "bar2"

这导致:

{:foo1=>"bar1", :foo2=>"bar2"} # a
{:foo1=>"bar1", :foo2=>"bar2"} # b

我希望它在哪里

{:foo1=>"bar1"}                # a
{:foo1=>"bar1", :foo2=>"bar2"} # b

现在我知道b = Marshal.load(Marshal.dump(a)),但这似乎有点矫枉过正,我想知道是否有更好的方法,因为我无法真正找到它。

2 个答案:

答案 0 :(得分:1)

你可以写

a = { k: 'dog' }
b = {}.merge(a)
  #=> {:k=>"dog"}
b[:cat] = 'meow'

a #=> {:k=>"dog"}
b #=> {:k=>"dog", :cat=>"meow"}

但我们警惕

a = { k: [:cow, :pig] }
b = {}.merge(a)
  #=> {:k=>[:cow, :pig]}
b[:k] << 'chicken'
  #=> [:cow, :pig, "chicken"]

a #=> {:k=>[:cow, :pig, "chicken"]}
b #=> {:k=>[:cow, :pig, "chicken"]}

a不是我们想要的。

确保您创建哈希深层副本的一种方法是使用Marshal#dumpMarshal#load

a = { :k=>[1, [2, [3, { :m=>[4] }]]] }
b = Marshal.load(Marshal.dump(a))
  #=> {:k=>[1, [2, [3, {:m=>[4]}]]]}

b[:k][-1][-1][-1][:m] << 5

a #=> {:k=>[1, [2, [3, {:m=>[4]}]]]}
b #=> {:k=>[1, [2, [3, {:m=>[4, 5]}]]]}

答案 1 :(得分:1)

Kernel#dupKernel#clone可以满足您的需求:

pselect()

按照你的要求,这是一个浅薄的副本,但是:

a = {foo1: "bar1"}
b = a.dup # or a.clone

b[:foo2] = "bar2"

p b
# {:foo1=>"bar1", :foo2=>"bar2"}
p a
# {:foo1=>"bar1"}