如何在Ruby中合并两个哈希而不覆盖重复键?

How can I merge two hashes without overwritten duplicate keys in Ruby?

是否有一种简单或优雅的方法来合并两个哈希而不会覆盖重复的键?

也就是说,如果密钥存在于原始哈希中,我不想更改其值。


如果你有两个哈希optionsdefaults,并且想要将defaults合并到options而不覆盖现有的键,那么你真正想做的是反过来:将options合并到defaults

1
options = defaults.merge(options)

或者,如果您使用Rails,您可以:

1
options.reverse_merge!(defaults)


标准Ruby库中有一种方法可以合并Hashes而不覆盖现有值或重新分配哈希值。

1
important_hash.merge!(defaults) { |key, important, default| important }


如果您的问题是原始哈希和第二个哈希都可能有重复的密钥而您不想在任何一个方向上覆盖,那么您可能需要进行简单的手动合并以进行某种冲突检查和处理:

1
2
3
4
5
6
7
hash2.each_key do |key|
  if ( hash1.has_key?(key) )
       hash1["hash2-originated-#{key}" ] = hash2[key]
  else
       hash1[key]=hash2[key]
  end
end

显然,这是非常基本的,并假设hash1没有任何称为"hash2-originated-whatever"的键 - 你可能最好只为键添加一个数字,使它成为key1,key2等等,直到你点击一个尚未在hash1中的。此外,我几个月没有做任何红宝石,所以这可能在语法上不正确,但你应该能够获得要点。

或者,将键的值重新定义为数组,以便hash1 [key]返回hash1的原始值和hash2的值。取决于你想要的结果是什么。


在这里你可以通过reverse_merge合并你的2哈希

1
2
3
4
5
6
7
8
9
10
11
order = {
 id: 33987,
 platform: 'web'
}

user = {
  name: 'Jhon Doe',
  email: '[email protected]'
}
newHash = oder.reverse_merge!(user)
render json: { data: newHash, status: 200 }