简体   繁体   中英

Merge two hashes with arrays by the same key Ruby

I need some help with Ruby. I have two hashes parsed from JSON. I use this code to parse files:

document = JSON.load File.new("hosts.txt")
file = JSON.load File.new("admins.txt")

The result are two big hashes like that:

document={"total"=>13, "subtotal"=>13, "page"=>1, "per_page"=>20,
          "search"=>nil, "sort"=>{"by"=>nil, "order"=>nil},
          "results"=>[
             {"ip"=>"10", "environment_id"=>7, 
                 "medium_id"=>nil, "name"=>"one", "id"=>1},
             {"ip"=>"15", "environment_id"=>7, 
                 "medium_id"=>nil, "name"=>"two", "id"=>1},
             {"ip"=>"10.5", "environment_id"=>6, 
                 "medium_id"=>nil, "name"=>"four", "id"=>1}]}

file={"admins"=>[
           {"name"=>"one", "surname"=>"Mark", "email"=>"mark@o.com"},
           {"name"=>"two", "surname"=>"Adam", "email"=>"Adam@o.com"},
           {"name"=>"four", "surname"=>"Ami", "email"=>"Ami@o.com"}]}

From the first hash I need only information from the results key, so I have done

data = document["results"]

I've done the same for the second hash:

people = file["admins"]

Now, when the "name" values are the same I want to move surname and email from the people array to data array and have another hash like this:

new = {"all_data"=>[
        {"ip"=>"10", "environment_id"=>7, "medium_id"=>nil,
           "name"=>"one", "id"=>1, "surname"=>"Mark", "email"=>"mark@o.com"},
        {"ip"=>"15", "environment_id"=>7, "medium_id"=>nil,
           "name"=>"two", "id"=>1, "surname"=>"Adam", "email"=>"Adam@o.com"},
        {"ip"=>"10.5", "environment_id"=>6, "medium_id"=>nil,
           "name"=>"four", "id"=>1, "surname"=>"Ami", "email"=>"Ami@o.com"}]}

Can you help me to do that and explain how it works?

personal_data = file['admins'].map(&:dup)
                              .group_by { |e| e.delete('name') }

the dup / delete trick above is not necessary, since merge below will be handled properly in any case, but it's here for the sake of semantic clarity.

document['results'].map do |h|
  h.merge(personal_data[h['name']].first) if personal_data[h['name']]
end

#⇒ [
#    {"ip"=>"10", "environment_id"=>7, "medium_id"=>nil, "name"=>"one",
#       "id"=>1, "surname"=>"Mark", "email"=>"mark@o.com"},
#    {"ip"=>"15", "environment_id"=>7, "medium_id"=>nil, "name"=>"two",
#       "id"=>1, "surname"=>"Adam", "email"=>"Adam@o.com"},
#    {"ip"=>"10.5", "environment_id"=>6, "medium_id"=>nil, "name"=>"four",
#       "id"=>1, "surname"=>"Ami", "email"=>"Ami@o.com"}]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM