简体   繁体   中英

Ruby convert array of hashes into one hash

The input hash array is something like this:

[{count: 111, date: A},{count: 222, date: B},{count: 333, date: C}]

I want convert it into:

{A => {count: 111}, B => {count: 222}, C => {count: 333}}

That's just a simplified version, the hash could be very large - I mean many keys.

a = [{count: 111, date: 'A'},{count: 222, date: 'B'},{count: 333, date: 'C'}]
Hash[a.map {|h| [h[:date], {count: h[:count]}]}]
# => {"A"=>{:count=>111}, "B"=>{:count=>222}, "C"=>{:count=>333}}
aoh = [{count: 111, date: 'A'},{count: 222, date: 'B'},{count: 333, date: 'C'}]
flat = Hash[aoh.map {|h| [h.delete(:date), h]}]
# => {"A"=>{:count=>111}, "B"=>{:count=>222}, "C"=>{:count=>333}}

This is simliar to @falsetru's solution, but slightly more general in that if there are more keys in the original hashes besides just :count and :date , they will all be preserved in the result:

aoh = [{count: 111, date: 'A', pos: 1},{count: 222, date: 'B', pos: 2},{count: 333, date: 'C', pos: 3}]
flat = Hash[aoh.map {|h| [h.delete(:date), h]}]
# => {"A"=>{:count=>111, :pos=>1}, "B"=>{:count=>222, :pos=>2}, "C"=>{:count=>333, :pos=>3}}

The Array#inject method is a good choice:

[{count: 111, date: 'A'},{count: 222, date: 'B'},{count: 333, date: 'C'}].inject({}) do |h, item|
  h[item[:date]] = {count: item[:count]}
  h
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