I have an array of
shop objects
which belong to city objects
- which belong to prefec开发者_运维问答ture objects
I'd like to end up with a hash listed by prefecture, then city, then frequency...
I came up with this, but it feels really un-rubylike..
city_by_prefecture = shop_list.reduce({}){ |h,e|
if h[e.prefecture.name].nil?
h[e.prefecture.name] = {e.city.name => 1}
elsif h[e.prefecture.name][e.city.name].nil?
h[e.prefecture.name][e.city.name] = 1
else
h[e.prefecture.name][e.city.name] += 1
end
h
}
There must be a DRY-er way to do this !
city_by_prefecture = shop_list.each_with_object({}){ |e,h|
h[e.prefecture.name] ||= Hash.new(0)
h[e.prefecture.name][e.city.name] += 1
}
shops = [
OpenStruct.new(:prefacture => "pre1", :city => "city1"),
OpenStruct.new(:prefacture => "pre1", :city => "city1"),
OpenStruct.new(:prefacture => "pre1", :city => "city2"),
OpenStruct.new(:prefacture => "pre2", :city => "city3"),
]
counts = Hash[shops.group_by(&:prefacture).map do |prefacture, shops_in_prefacture|
[prefacture, Hash[shops_in_prefacture.group_by(&:city).map do |city, shops_in_city|
[city, shops_in_city.size]
end]]
end]
# {"pre1"=>{"city1"=>2, "city2"=>1}, "pre2"=>{"city3"=>1}}
精彩评论