24

私は次のようなハッシュを持っています:

h = {'name' => 'sayuj', 
     'age' => 22, 
     'project' => {'project_name' => 'abc', 
                   'duration' => 'prq'}}

このハッシュの複製が必要です。変更は元のハッシュに影響を与えるべきではありません。

試してみると、

d = h.dup # or d = h.clone
d['name'] = 'sayuj1'
d['project']['duration'] = 'xyz'

p d #=> {"name"=>"sayuj1", "project"=>{"duration"=>"xyz", "project_name"=>"abc"}, "age"=>22}
p h #=> {"name"=>"sayuj", "project"=>{"duration"=>"xyz", "project_name"=>"abc"}, "age"=>22}

ここでは、が別のハッシュ オブジェクトであるproject['duration']ため、元のハッシュで is が変更されていることがわかります。project

dupedハッシュをまたはcloned再帰的にしたい。どうすればこれを達成できますか?

4

5 に答える 5

40

Rubyでディープコピーを作成する方法は次のとおりです

d = Marshal.load( Marshal.dump(h) )
于 2012-01-03T10:13:21.467 に答える
1

これはかなり古い質問への回答ですが、似たようなものを実装しているときにたまたま見つけたので、より効率的な方法が必要だと思いました。

上記のような単純な 2 レベルのディープ ハッシュの場合、次のようなこともできます。

d = h.inject({}) {|copy, (key, value)| 
    copy[key] = value.dup rescue value; copy
}

それぞれ数百バイトの 4k 要素を持つハッシュのハッシュでテストを実行したところ、Marshal.dump/load よりも約 50% 高速でした。

もちろん、「project_name」フィールドの値などのハッシュがある場合は機能しないため、完全ではありませんが、単純な 2 レベルのハッシュの場合は、優れた/高速に機能します。

于 2013-10-09T20:02:56.610 に答える