[Ruby] 再帰的group_by
やりたいこと
こういうデータ↓を
[ { prefecture: '埼玉県', city: '深谷市', town: '北根', address: '3-5' }, { prefecture: '埼玉県', city: '深谷市', town: '北根', address: '3-7-19' }, { prefecture: '埼玉県', city: '深谷市', town: '堀米', address: '1-11-14' }, { prefecture: '埼玉県', city: 'さいたま市中央区', town: '新中里', address: '1-2-17' }, { prefecture: '埼玉県', city: 'さいたま市中央区', town: '新都心', address: '1-6-13' }, { prefecture: '東京都', city: '品川区', town: '西中延', address: '3-5' }, ]
こう↓したい
{ "埼玉県"=> { "深谷市"=> { "北根"=>["3-5", "3-7-19"], "堀米"=>["1-11-14"] }, "さいたま市中央区"=> { "新中里"=>["1-2-17"], "新都心"=>["1-6-13"] } }, "東京都"=> { "品川区"=> { "西中延"=>["3-5"] } } }
再帰的group_by
参考:
module Enumerable def recursive_group_by(*props, &block) groups = group_by{ |e| e[props.first] } next_props = props.drop(1) if next_props.empty? block_given? ? block.call(groups) : groups else groups.transform_values do |e| e.recursive_group_by(*next_props, &block) end end end end data = [ { prefecture: '埼玉県', city: '深谷市', town: '北根', address: '3-5' }, { prefecture: '埼玉県', city: '深谷市', town: '北根', address: '3-7-19' }, { prefecture: '埼玉県', city: '深谷市', town: '堀米', address: '1-11-14' }, { prefecture: '埼玉県', city: 'さいたま市中央区', town: '新中里', address: '1-2-17' }, { prefecture: '埼玉県', city: 'さいたま市中央区', town: '新都心', address: '1-6-13' }, { prefecture: '東京都', city: '品川区', town: '西中延', address: '3-5' }, ] new_data = data.recursive_group_by(:prefecture, :city, :town) do |groups| groups.transform_values do |v| v.map { |x| x[:address] } end end pp data puts '--' pp new_data
結果
[{:prefecture=>"埼玉県", :city=>"深谷市", :town=>"北根", :address=>"3-5"}, {:prefecture=>"埼玉県", :city=>"深谷市", :town=>"北根", :address=>"3-7-19"}, {:prefecture=>"埼玉県", :city=>"深谷市", :town=>"堀米", :address=>"1-11-14"}, {:prefecture=>"埼玉県", :city=>"さいたま市中央区", :town=>"新中里", :address=>"1-2-17"}, {:prefecture=>"埼玉県", :city=>"さいたま市中央区", :town=>"新都心", :address=>"1-6-13"}, {:prefecture=>"東京都", :city=>"品川区", :town=>"西中延", :address=>"3-5"}] -- {"埼玉県"=> {"深谷市"=>{"北根"=>["3-5", "3-7-19"], "堀米"=>["1-11-14"]}, "さいたま市中央区"=>{"新中里"=>["1-2-17"], "新都心"=>["1-6-13"]}}, "東京都"=>{"品川区"=>{"西中延"=>["3-5"]}}}