Reputation: 1975
I have an array of hashes like this:
[
{ name: 'Pratha', email: '[email protected]' },
{ name: 'John', email: '[email protected]' },
{ name: 'Clark', email: '[email protected]' },
]
And this is second group array of hashes:
[
{ name: 'AnotherNameSameEmail', email: '[email protected]' },
{ name: 'JohnAnotherName', email: '[email protected]' },
{ name: 'Mark', email: '[email protected]' },
]
What I want is, merge these two arrays into one, merge based on :email
and keep latest (or first) :name
.
Expected Result (latest name overrided):
[
{ name: 'AnotherNameSameEmail', email: '[email protected]' },
{ name: 'JohnAnotherName', email: '[email protected]' },
{ name: 'Mark', email: '[email protected]' },
{ name: 'Clark', email: '[email protected]' },
]
or (first name preserved)
[
{ name: 'Pratha', email: '[email protected]' },
{ name: 'John', email: '[email protected]' },
{ name: 'Mark', email: '[email protected]' },
{ name: 'Clark', email: '[email protected]' },
]
So, basically, I want to group by :email
, retain one :name
, drop dupe emails.
The examples found on SO is creates an array of values for :name
.
Ruby 2.6.3
Upvotes: 1
Views: 121
Reputation: 11193
Maybe you could just call Array#uniq with a block on email key of the concatenation (Array#+) of the two arrays:
(ary1 + ary2).uniq { |h| h[:email] }
Upvotes: 3
Reputation: 110725
a1 = [
{ name: 'Pratha', email: '[email protected]' },
{ name: 'John', email: '[email protected]' },
{ name: 'Clark', email: '[email protected]' },
]
a2 = [
{ name: 'AnotherNameSameEmail', email: '[email protected]' },
{ name: 'JohnAnotherName', email: '[email protected]' },
{ name: 'Mark', email: '[email protected]' },
]
Let's first keep the last:
(a1+a2).each_with_object({}) { |g,h| h.update(g[:email]=>g) }.values
#=> [{:name=>"AnotherNameSameEmail", :email=>"[email protected]"},
# {:name=>"JohnAnotherName", :email=>"[email protected]"},
# {:name=>"Clark", :email=>"[email protected]"},
# {:name=>"Mark", :email=>"[email protected]"}]
To keep the first, do the same with (a1+a2)
replaced with (a2+a1)
, to obtain:
#=> [{:name=>"Pratha", :email=>"[email protected]"},
# {:name=>"John", :email=>"[email protected]"},
# {:name=>"Mark", :email=>"[email protected]"},
# {:name=>"Clark", :email=>"[email protected]"}]
Upvotes: 2