如何根据哈希值合并哈希数组,但不合并值,而是覆盖

时间:2019-05-24 17:29:16

标签: ruby

我有一系列这样的哈希值:

[
  { name: 'Pratha', email: 'c@f.com' },
  { name: 'John', email: 'j@g.com' },
  { name: 'Clark', email: 'x@z.com' },
]

这是第二组哈希数组:

[
  { name: 'AnotherNameSameEmail', email: 'c@f.com' },
  { name: 'JohnAnotherName', email: 'j@g.com' },
  { name: 'Mark', email: 'd@o.com' },
]

我想要的是将这两个数组合并为一个,基于:email合并并保持最新(或第一个):name

预期结果(已覆盖最新名称):

[
  { name: 'AnotherNameSameEmail', email: 'c@f.com' },
  { name: 'JohnAnotherName', email: 'j@g.com' },
  { name: 'Mark', email: 'd@o.com' },
  { name: 'Clark', email: 'x@z.com' },
]

或(保留名字)

[
  { name: 'Pratha', email: 'c@f.com' },
  { name: 'John', email: 'j@g.com' },
  { name: 'Mark', email: 'd@o.com' },
  { name: 'Clark', email: 'x@z.com' },
]

因此,基本上,我想按:email分组,保留一个 :name,删除重复邮件。

在SO上找到的示例是为:name创建一个值数组。

Ruby 2.6.3

2 个答案:

答案 0 :(得分:3)

也许您可以使用两个数组的串联(Array#uniq)的电子邮件密钥上的一个块来调用Array#+

(ary1 + ary2).uniq { |h| h[:email] }

答案 1 :(得分:2)

a1 = [
  { name: 'Pratha', email: 'c@f.com' },
  { name: 'John', email: 'j@g.com' },
  { name: 'Clark', email: 'x@z.com' },
]

a2 = [
  { name: 'AnotherNameSameEmail', email: 'c@f.com' },
  { name: 'JohnAnotherName', email: 'j@g.com' },
  { name: 'Mark', email: 'd@o.com' },
]

让我们先保留最后一个:

(a1+a2).each_with_object({}) { |g,h| h.update(g[:email]=>g) }.values
  #=> [{:name=>"AnotherNameSameEmail", :email=>"c@f.com"},
  #    {:name=>"JohnAnotherName", :email=>"j@g.com"},
  #    {:name=>"Clark", :email=>"x@z.com"},
  #    {:name=>"Mark", :email=>"d@o.com"}]

要保留第一个,请用(a1+a2)替换(a2+a1)来执行以下操作,以获得:

  #=> [{:name=>"Pratha", :email=>"c@f.com"},
  #    {:name=>"John", :email=>"j@g.com"},
  #    {:name=>"Mark", :email=>"d@o.com"},
  #    {:name=>"Clark", :email=>"x@z.com"}]