Ruby 递归复制/克隆

发布于 2024-12-24 02:27:49 字数 723 浏览 3 评论 0 原文

我有一个像这样的哈希值:

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'] 已更改,因为 project 是另一个哈希对象。

我希望哈希被递归地欺骗克隆。我怎样才能实现这个目标?

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.

I want the hash to be duped or cloned recursively. How can I achieve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

找个人就嫁了吧 2024-12-31 02:27:49

以下是如何在 Ruby 中进行深复制

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

Here's how you make deep copies in Ruby

d = Marshal.load( Marshal.dump(h) )
铃予 2024-12-31 02:27:49

如果您使用 Rails:Hash.deep_dup

If you are in Rails: Hash.deep_dup

零度℉ 2024-12-31 02:27:49

如果 Marhal #dump/load 对不起作用,对于 有一个 Hash 的方法 #deep_dup,因此您可以:

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

h1 = h.deep_dup

In case the Marchal #dump/load pair isn't work, for there is a Hash's method #deep_dup, so you can:

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

h1 = h.deep_dup
最终幸福 2024-12-31 02:27:49

这是一个相当老的问题的答案,但我在实现类似的东西时偶然发现了它,我想我会提出一种更有效的方法。

对于像上面这样的简单的两级深度哈希,您还可以执行以下操作:

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

我对具有 4k 元素的哈希哈希进行了测试,每个元素有几百个字节,它比 Marshal.dump 快约 50% /load

当然,它并不完整,因为如果你有一个哈希值,例如“project_name”字段的值,它就不起作用,但对于简单的 2 级哈希,它工作得很好/更快。

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

Of course, it's not as complete, as it won't work if you have a hash as, e.g., the value of the 'project_name' field, but for a simple 2 level hash, it works great / faster.

被你宠の有点坏 2024-12-31 02:27:49

另一种选择是使用 full_dup gem(完全公开:我是该 gem 的作者),它处理数组、散列、结构,并且可扩展到用户定义的类。

使用方法:

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

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

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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文