2017-07-08 35 views
0

什麼是在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))但是,似乎有點矯枉過正,和我想知道是否有更好的辦法,因爲我找不到它。

+1

它適用於'dup'我... –

+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

Kernel#dupKernel#clone不只是你想要什麼:

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

b[:foo2] = "bar2" 

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

正如你要求,這是一個淺拷貝,雖然:

a = {foo1: ["bar1"]} 
b = a.clone 

b[:foo1] << 'bar2' 
b[:foo3] = 'bar3' 

p a 
# {:foo1=>["bar1", "bar2"]} 
p b 
# {:foo1=>["bar1", "bar2"], :foo3=>"bar3"}