0

I have below hash. How to get unique and merged hash.

[
 {
  "email"=>"user_name@aaa.com",
  "expression"=>"aaa",
  "name"=>"bbb",
  "roles"=>[:admin]
  },

  {
   "email"=>"user_name@aaa.com",
   "expression"=>"aaa",
   "name"=>"bbb",
   "roles"=>[:manager]
  }
]

I want below result hash that unique by email and merged by roles.

[
  {
    "email"=>"user_name@aaa.com",
    "expression"=>"aaa",
    "name"=>"bbb",
    "roles"=>[:admin, :manager]
  }
]

Help me.

mbt
  • 29
  • 9

3 Answers3

2

Try this one

a.group_by { |item| item["email"] }.each_with_object([]) do |(_, items), arr| 
  arr.concat([items.first.merge("roles" => items.flat_map { |item| item["roles"] }.uniq)])
end
Ursus
  • 29,643
  • 3
  • 33
  • 50
1
input.
  group_by { |e| e['email'] }.
  map do |_, v|
    v.reduce do |acc, h|
      acc.merge(h) { |_, v1, v2| v1 == v2 ? v1 : [*v1, *v2] }
    end
  end
#⇒ [{"email"=>"user_name@aaa.com",
#    "expression"=>"aaa",
#    "name"=>"bbb",
#    "roles"=>[:admin, :manager]}]
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
0
arr = [{ "email"=>"user_name@aaa.com", "expression"=>"aaa", "name"=>"bbb",
         "roles"=>[:admin] },
       { "email"=>"user_name@aaa.com", "expression"=>"aaa", "name"=>"bbb",
         "roles"=>[:manager] }]

arr.first.merge("roles"=>arr.map { |h| h["roles"].first })
  #=> {"email"=>"user_name@aaa.com", "expression"=>"aaa", "name"=>"bbb",
  #    "roles"=>[:admin, :manager]}

The steps are as follows.

h = arr.first
  #=> {"email"=>"user_name@aaa.com", "expression"=>"aaa", "name"=>"bbb",
  #    "roles"=>[:admin]}
a = arr.map { |h| h["roles"].first }
  #=> [:admin, :manager]
g = { "roles"=>a }
  #=> {"roles"=>[:admin, :manager]}
h.merge(g)
  #=> {"email"=>"user_name@aaa.com", "expression"=>"aaa", "name"=>"bbb",
  #    "roles"=>[:admin, :manager]}

Note that Ruby permits a hash as a method argument to be written as a sequence of its key value pairs. For example:

receiver.doit({ a: 1, b: 2})

can be written

receiver.doit(a: 1, b: 2)
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100