【ruby】根据首字发音对字符串进行分组


在日本的系统中，经常可以见到系统根据选项的第一个字发音的所在行来对其进行分组。这样做的好处是让繁多的选项变得有序化，可以让用户更加快捷地找到自己所需的选项。

首先，我们需要在数据库中储存地址的カナ信息，例如：

```ruby
=> ZipCode(code: string, state_code: integer, state: string, state_kana: string, city_code: integer, city: string, city_kana: string, town_code: integer, town: string, town_kana: string, special: boolean, created_at: datetime, updated_at: datetime)
```

在准备好数据后，我们根据数据中的カナ信息来对数据进行排序：

```ruby
def group_by_kana(zip_codes, column)
	return zip_codes unless zip_codes[0].respond_to? column
	key = %w(ア カ サ タ ナ ハ マ ヤ ラ ワ)
	zip_codes.group_by do |zip_code|
		key[key.index{|i| i > zip_code.send(column)[0]}.to_i - 1]
	end
end
  
zip_codes = ZipCode.where(state_code: 13).group(:city_code).limit(5)
#=> [#<ZipCode code: "1000000", state_code: 13, state: "東京都", state_kana: "トウキョウト", city_code: 13101, city: "千代田区", city_kana: "チヨダク", town_code: 131010000, town: nil, town_kana: nil, special: true, created_at: "2016-01-15 08:50:43", updated_at: "2016-01-18 04:20:35">,
 #<ZipCode code: "1030000", state_code: 13, state: "東京都", state_kana: "トウキョウト", city_code: 13102, city: "中央区", city_kana: "チュウオウク", town_code: 131020000, town: nil, town_kana: nil, special: true, created_at: "2016-01-15 08:50:47", updated_at: "2016-01-18 04:20:36">,
 #<ZipCode code: "1050000", state_code: 13, state: "東京都", state_kana: "トウキョウト", city_code: 13103, city: "港区", city_kana: "ミナトク", town_code: 131030000, town: nil, town_kana: nil, special: true, created_at: "2016-01-15 08:50:50", updated_at: "2016-01-18 04:20:37">,
 #<ZipCode code: "1600000", state_code: 13, state: "東京都", state_kana: "トウキョウト", city_code: 13104, city: "新宿区", city_kana: "シンジュクク", town_code: 131040000, town: nil, town_kana: nil, special: true, created_at: "2016-01-15 08:50:54", updated_at: "2016-01-18 04:20:40">,
 #<ZipCode code: "1120000", state_code: 13, state: "東京都", state_kana: "トウキョウト", city_code: 13105, city: "文京区", city_kana: "ブンキョウク", town_code: 131050000, town: nil, town_kana: nil, special: true, created_at: "2016-01-15 08:50:58", updated_at: "2016-01-18 04:20:41">]

group_by_kana(zip_codes, :city_kana)

{"タ"=>
  [#<ZipCode code: "1000000", state_code: 13, state: "東京都", state_kana: "トウキョウト", city_code: 13101, city: "千代田区", city_kana: "チヨダク", town_code: 131010000, town: nil, town_kana: nil, special: true, created_at: "2016-01-15 08:50:43", updated_at: "2016-01-18 04:20:35">,
   #<ZipCode code: "1030000", state_code: 13, state: "東京都", state_kana: "トウキョウト", city_code: 13102, city: "中央区", city_kana: "チュウオウク", town_code: 131020000, town: nil, town_kana: nil, special: true, created_at: "2016-01-15 08:50:47", updated_at: "2016-01-18 04:20:36">],
 "マ"=>
  [#<ZipCode code: "1050000", state_code: 13, state: "東京都", state_kana: "トウキョウト", city_code: 13103, city: "港区", city_kana: "ミナトク", town_code: 131030000, town: nil, town_kana: nil, special: true, created_at: "2016-01-15 08:50:50", updated_at: "2016-01-18 04:20:37">],
 "サ"=>
  [#<ZipCode code: "1600000", state_code: 13, state: "東京都", state_kana: "トウキョウト", city_code: 13104, city: "新宿区", city_kana: "シンジュクク", town_code: 131040000, town: nil, town_kana: nil, special: true, created_at: "2016-01-15 08:50:54", updated_at: "2016-01-18 04:20:40">],
 "ハ"=>
  [#<ZipCode code: "1120000", state_code: 13, state: "東京都", state_kana: "トウキョウト", city_code: 13105, city: "文京区", city_kana: "ブンキョウク", town_code: 131050000, town: nil, town_kana: nil, special: true, created_at: "2016-01-15 08:50:58", updated_at: "2016-01-18 04:20:41">]}
```