2017-07-08 5 views
0

Rubyでハッシュを複製し、元のものから独立させる最良の方法は何ですか?たとえば、次のように独立したハッシュ(浅いコピー)に重複したハッシュ

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

これは、その結果:

私はそれが

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

ようにしたいと思い

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

今、私はおよそb = Marshal.load(Marshal.dump(a))を知っているが、それは少しやり過ぎのように思える、とI私は本当にそれを見つけることができないので、より良い方法があるかどうか疑問に思っていた。

+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のは、私たちが望むものではありません。

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"} 

あなたはハッシュのディープコピーを作成確保する

一つの方法は、Marshal#dumpMarshal#loadを使用することですしかし、それは浅いコピーです:

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

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

p a 
# {:foo1=>["bar1", "bar2"]} 
p b 
# {:foo1=>["bar1", "bar2"], :foo3=>"bar3"} 
関連する問題