group_by multiple times in ruby

  • A+
Category:Languages

I have an array of hashes called events:

events = [   {:name => "Event 1", :date => "2019-02-21 08:00:00", :area => "South", :micro_area => "A"},   {:name => "Event 2", :date => "2019-02-21 08:00:00", :area => "South", :micro_area => "A"},   {:name => "Event 3", :date => "2019-02-21 08:00:00", :area => "South", :micro_area => "B"},   {:name => "Event 4", :date => "2019-02-21 08:00:00", :area => "South", :micro_area => "B"},   {:name => "Event 5", :date => "2019-02-21 08:00:00", :area => "North", :micro_area => "A"},   {:name => "Event 6", :date => "2019-02-21 08:00:00", :area => "North", :micro_area => "A"},   {:name => "Event 7", :date => "2019-02-21 08:00:00", :area => "North", :micro_area => "B"},   {:name => "Event 8", :date => "2019-02-21 08:00:00", :area => "North", :micro_area => "B"} ] 

I want to know how to group_by first date, then area then micro_area to end up with a single array of hashes for example:

[   {     "2019-02-21 08:00:00": {       "South": {         "A": [           {:name=>"Event 1", :date=>"2019-02-21 08:00:00", :area=>"South", :micro_area=>"A" },           {:name=>"Event 2", :date=>"2019-02-21 08:00:00", :area=>"South", :micro_area=>"A" }         ],         "B": [           {:name=>"Event 3", :date=>"2019-02-21 08:00:00", :area=>"South", :micro_area=>"B" },           {:name=>"Event 4", :date=>"2019-02-21 08:00:00", :area=>"South", :micro_area=>"B" }         ]         },       "North": {         "A": [           {:name=>"Event 5", :date=>"2019-02-21 08:00:00", :area=>"North", :micro_area=>"A" },           {:name=>"Event 6", :date=>"2019-02-21 08:00:00", :area=>"North", :micro_area=>"A" }         ],         "B": [           {:name=>"Event 7", :date=>"2019-02-21 08:00:00", :area=>"North", :micro_area=>"B" },           {:name=>"Event 8", :date=>"2019-02-21 08:00:00", :area=>"North", :micro_area=>"B" }         ]         }     }   } ]  

Trying events.group_by { |r| [r[:date], r[:area], r[:micro_area]] } doesn't seem too work the way I want it to.

 


I think following will work for you,

events = [   { name: 'Event 1', date: '2019-02-21 08:00:00', area: 'South', micro_area: 'A' } ]  events.group_by { |x| x[:date] }.transform_values do |v1|   v1.group_by { |y| y[:area] }.transform_values do |v2|     v2.group_by { |z| z[:micro_area] }   end end # { #   "2019-02-21 08:00:00"=>{ #     "South"=>{ #       "A"=>[ #         {:name=>"Event 1", :date=>"2019-02-21 08:00:00", :area=>"South", :micro_area=>"A"} #       ] #     } #   } # }    

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: