[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"]}}}