简体   繁体   中英

Merge array of hashes and re-sort it

I have array of hashes it looks like

arr = [
  {"partner_name"=>"Bell", "publisher_name"=>"News - Calgary", "mn"=>"", "mid"=>415},
  {"partner_name"=>"Bell", "publisher_name"=>"News - Vancouver Island", "mn"=>"Module 2.0 ", "mid"=>4528},
  {"partner_name"=>"Bell", "publisher_name"=>"News - Atlantic", "mn"=>"Module 2.0 ", "mid"=>4531},
  {"partner_name"=>"Bell", "publisher_name"=>"News - Kitchener", "mn"=>"Module 2.0 ", "mid"=>4535},
  {"partner_name"=>"Bell", "publisher_name"=>"News - London", "mn"=>"Module 2.0 ", "mid"=>4536},
  {"partner_name"=>"Bell", "publisher_name"=>"News - Ottawa", "mn"=>"Module 2.0 ", "mid"=>4539},
  {"partner_name"=>"Bell", "publisher_name"=>"News - Regina", "mn"=>"Module 2.0 ", "mid"=>4540},
  {"partner_name"=>"Bell", "publisher_name"=>"News - Saskatoon", "mn"=>"Module 2.0 ", "mid"=>4541},
  {"partner_name"=>"Bell", "publisher_name"=>"News - Toronto", "mn"=>"Module 2.0 ", "mid"=>4542},
  {"partner_name"=>"Bell", "publisher_name"=>"News - Windsor", "mn"=>"Module 2.0 ", "mid"=>4544},
  {"partner_name"=>"Bell", "publisher_name"=>"CP24", "mn"=>"Module 2.0 Platform", "mid"=>5413},
]

i have tried to do arr.group_by{|el|el['partner_name']}

i want to achieve this result

{
  partner:'Bell',
  publishers: [
    {name:'News - Vancouver Island'},
    {name:'News - Vancouver Island'},
    # ... and others
  ],
  modules:[
    {mn: val, mid: id_val},
    # ...
  ],
}

Anything like this?

arr.group_by { |item| item["partner_name"] }.
    map do |partner_name, data| 
      publishers = data.map { |h| Hash[:name, h["publisher_name"]] }
      modules = data.map { |h| Hash[:mn, h["mn"], :mid, h["mid"]] }
      Hash[:partner, partner_name, :publishers, publishers, :modules, modules] 
    end

group_by and map

result = arr.
  group_by { |r| r["partner_name"] }.
  map do |(partner_name, records)|
    {
      name: partner_name,
      publishers: records.map do |r|
        { name: r["publisher_name"] }
      end,
      modules: records.map do |r|
        { mn: r["mn"], mid: r["mid"] }
      end,
    }
  end

Since the Hashes in the Array already appear to be scoped to a partner a simple implementation could look like:

new_h = {partner: arr.first["partner_name"],publishers: [],modules: []}
arr.each_with_object(new_h) do |h, result| 
  result[:publishers] << {name: h["publisher_name"]}
  result[:modules] << h.slice("mn","mid")
end

If they are not scoped as shown then just group and map the same:

arr.group_by {|h| h["partner_name"]}.map do |name,values|
  new_h = {partner: name,publishers: [],modules: []}
  values.each_with_object(new_h) do |h, result| 
    result[:publishers] << {name: h["publisher_name"]}
    result[:modules] << h.slice("mn","mid")
  end
end

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