简体   繁体   English

Ruby递归/克隆递归

[英]Ruby dup/clone recursively

I have a hash like: 我有一个哈希:

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

I need a dup of this hash, the change should not affect the original hash. 我需要一个这个哈希的副本,更改不应该影响原始哈希。

When I try, 当我尝试时,

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}

Here you can see the project['duration'] is changed in the original hash because project is another hash object. 在这里,您可以看到project['duration']在原始哈希中更改,因为project是另一个哈希对象。

I want the hash to be duped or cloned recursively. 我想哈希被dupedcloned递归。 How can I achieve this? 我怎样才能做到这一点?

以下是如何在Ruby中制作深层副本

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

In case the Marchal #dump/load pair isn't work, for there is a Hash 's method #deep_dup , so you can: 如果Marchal #dump/load #deep_dup作用,对于有一个Hash的方法#deep_dup ,所以你可以:

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

h1 = h.deep_dup

如果你在Rails: Hash.deep_dup

This is an answer to a reasonably old question, but I happened upon it while implementing something similar, thought I'd chime in for a more efficient method. 这是一个相当古老的问题的答案,但我在实现类似的事情时发生了它,认为我想要一个更有效的方法。

For the simple, two level deep hash like above, you can also do something like this: 对于像上面这样简单的两级深度哈希,你也可以这样做:

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

I ran a test on a hash of hashes with 4k elements, each a few hundred bytes, and it was about 50% faster than the Marshal.dump/load 我在一个带有4k元素的哈希散列上运行测试,每个元素都有几百个字节,它比Marshal.dump / load快约50%

Of course, it's not as complete, as it won't work if you have a hash as, eg, the value of the 'project_name' field, but for a simple 2 level hash, it works great / faster. 当然,它并不完整,因为如果你有一个哈希值,例如'project_name'字段的值,它将无法工作,但对于一个简单的2级哈希,它可以很好/更快。

Another alternative is to use the full_dup gem (full disclosure: I am the author of that gem) that handles arrays, hashes, structs, and is extendable to user defined classes. 另一种方法是使用full_dup gem(完全披露:我是该gem的作者)来处理数组,散列,结构,并且可以扩展到用户定义的类。

To use: 使用:

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

Also note that full_dup handles complex data relationships including those with loops or recursion. 另请注意,full_dup处理复杂的数据关系,包括具有循环或递归的关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM