如何在Ruby中将一个哈希与另一个哈希组合

56

我有两个哈希表...

a = {:a => 5}
b = {:b => 10}

I want...

c = {:a => 5,:b => 10}

如何创建哈希 c?


1.9.3p194 :001 > hash1 = {:a=>5} => {:a=>5} 1.9.3p194 :002 > hash2 = {:b=>10} => {:b=>10} 1.9.3p194 :003 > hash3 = hash1.merge(hash2) => {:a=>5, :b=>10} 1.9.3p194 :004 > hash3 => {:a=>5, :b=>10} 1.9.3p194 :005 > - thefonso
4个回答

84

如果你只是进行交错操作,那么这就是一个相当简单的操作:

c = a.merge(b)

如果你想将这些值实际相加,那会有些棘手,但并非不可能:

c = a.dup
b.each do |k, v|
  c[k] ||= 0
  c[k] += v
end

a.dup 的原因是为了避免破坏 a 哈希表中的值,但如果您不关心,可以跳过此部分。使用 ||= 确保它以默认值 0 开始,因为 nil + 1 是无效的。


33

(TL;DR:hash1.merge(hash2)

众所周知,您可以使用合并方法来解决问题。但是使用合并方法还是存在一些问题。以下是原因。

person1 = {"name" => "MarkZuckerberg",  "company_name" => "Facebook", "job" => "CEO"}

person2 = {"name" => "BillGates",  "company_name" => "Microsoft", "position" => "Chairman"}

看看这两个字段名和公司名称。这里的name和company_name在两个哈希表中都是相同的(指键)。而工作和职位则有不同的键。

当你尝试合并两个哈希表person1和person2时,如果person1和person2中的键相同,则person2的键值将覆盖person1的键值。因为这里第二个哈希表中的字段将覆盖第一个哈希表中相同的字段。这里的name和company name是相同的。看看结果。

people  = person1.merge(person2)

 Output:  {"name"=>"BillGates", "company_name"=>"Microsoft", 
        "job"=>"CEO", "position"=>"Chairman"}
然而,如果您不希望第二个哈希覆盖第一个哈希。您可以像这样做
  people  = person1.merge(person2) {|key, old, new| old}

  Output:   {"name"=>"MarkZuckerberg", "company_name"=>"Facebook", 
            "job"=>"CEO", "position"=>"Chairman"} 

使用merge()时,这只是一个简短的提示。


1
感谢您在回复中包含了(更)完整的合并功能! :) +1 - Zackkenyon
你今天是我的英雄。我正好在找这个。 - Neeraj Gupta
1
碰撞是需要考虑的重要因素!但你的解决方案与 people = person2.merge(person1) 相同,对吗?在这种情况下,块是不必要的,但如果您想要处理更复杂的碰撞,则非常有用。它也适用于 merge!(破坏性版本)。 - Neal Gokli
奖励TL;DR! - fatfrog

11

1

使用合并方法:

c = a.merge b

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接