Ruby递归/克隆递归

我有一个哈希:

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' pd #=> {"name"=>"sayuj1", "project"=>{"duration"=>"xyz", "project_name"=>"abc"}, "age"=>22} ph #=> {"name"=>"sayuj", "project"=>{"duration"=>"xyz", "project_name"=>"abc"}, "age"=>22} 

在这里你可以看到project['duration']在原始哈希中被更改,因为project是另一个哈希对象。

我想要递归地duped或克隆哈希。 我怎样才能做到这一点?

这是你如何在Ruby中制作深层副本

 d = Marshal.load( Marshal.dump(h) ) 

如果Marchal #dump/load #deep_dup作用,对于rails,有一个Hash的方法#deep_dup ,所以你可以:

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

如果你在Rails: Hash.deep_dup

这是一个相当古老的问题的答案,但我在实现类似的东西时遇到了它,认为我想要一个更有效的方法。

对于像上面这样简单的两级深度哈希,你也可以这样做:

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

我在一个带有4k元素的哈希散列上运行测试,每个元素都有几百个字节,比Marshal.dump / load快约50%

当然,它并不完整,因为如果你有一个哈希值,例如’project_name’字段的值,它将无法工作,但对于一个简单的2级哈希,它可以很好/更快。

另一种方法是使用full_dup gem(完全披露:我是该gem的作者)来处理数组,散列,结构,并且可以扩展到用户定义的类。

使用:

 require 'full_dup' # Other code omitted ... d = h.full_dup 

另请注意,full_dup处理复杂的数据关系,包括具有循环或递归的关系。

    Interesting Posts