首页 > 解决方案 > ruby 中的递归函数正在覆盖 cloned(object.dup) 变量的嵌套属性

问题描述

我有一个这样的哈希:

entity = {1=> nil, 2 => {3 => nil, 4 => 1}}

我编写了一个函数,它可以使用递归删除给定实体的空值。

def clear_null_values(entity)
   entity.each do |key, value|
     if value == nil || value.blank?
       entity.delete(key)
     elsif value.is_a? Hash
       clear_null_values(value)
       entity.delete(key) if value.blank?
     end
   end
end 

而且我还需要原始实体用于其他目的。所以我复制了哈希变量,然后清除了空值。

final_entity = entity.dup
clear_null_values(entity)
puts entity
puts final_entity

结果:

{2 => {4 => 1}}
{1=> nil, 2 => {4 => 1}} # the nested values are overwritten.

理想情况下,final_entity 应该与原始实体相同。

问题1:为什么entity.dup复制只有outerhash?

问题2:如何使final_entity 完全复制原始实体,即即使我们修改实体,那么final_entity 也不应该改变?

标签: ruby-on-railsrubyhashclonedup

解决方案


尝试deep_dup改用,您的原始代码仅dup-ed 最外层的哈希。

final_entity = entity.deep_dup
clear_null_values(entity)
puts entity
puts final_entity

输出:

{2=>{4=>1}}
{1=>nil, 2=>{3=>nil, 4=>1}}

注意:Rails 还添加了Hash#compact,您可以使用它来简化clear_null_values.


推荐阅读