ブログトップ 記事一覧 ログイン 無料ブログ開設

プログラマーkkの勉強/成長ブログ@ライブレボリューション このページをアンテナに追加 RSSフィード Twitter

IT技術ブログ プログラミング・プログラマランキングへ 人気ブログランキングへ Add to Google Subscribe with livedoor Reader
この日記のはてなブックマーク数       ◆◆このブログのサイトマップへ◆◆



ジェームス・スキナーの隠されていた特別音声 期間限定ストリーミングプレゼント

2009年10月27日 Rubyで氏名を五十音順(辞書順)に並び替える

Rubyで氏名を五十音順(辞書順)に並び替える

MySQLのorderだと、五十音順がうまく並び替えができなかった。

例えば、辞書順だと、「わだ」、「わたなべ」の順になるはずが、

MySQLだと、「わたなべ」、「わだ」の順になる。

つまり、濁点が後ろに来てしまう。

そういうわけなので、Rubyを使って強引に並び替えることにした。

def sort_by_name(users=[])
  origin = "a-zA-Zァ-ン0-9ぁぃぅぇぉがぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽゃゅょっゎァィゥェォガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポャュョッヮ"
  normalize = "a-zA-Zぁ-ん0-9あいうえおかきくけこさしすせそたちつてとはひふへほはひふへほやゆよつわあいうえおかきくけこさしすせそたちつてとはひふへほはひふへほやゆよつわ"

  users.sort!{|a,b|
    [a.family_name_kana.tr(origin, normalize), a.first_name_kana.tr(origin, normalize)] <=> 
    [b.family_name_kana.tr(origin, normalize), b.first_name_kana.tr(origin, normalize)]
  }
end

users = User.find(:all)
sort_by_name(users)

  • ポイント
    • trを使って全角英数字を半角に変え、濁点・半濁点のある文字は濁点・半濁点をなくし、それをsortで並び替える。
    • カタカナとひらがなが混ざっている場合があるので、カタカナはひらがなに変換してからsortする。
    • 氏名は、苗字と名前を別のカラムにいれているので、sortの中で配列を使って苗字、名前の順で五十音順にsortする。

  • 追記
  users.sort!{|a,b|
    [a.family_name_kana.tr(origin, normalize), a.first_name_kana.tr(origin, normalize)] <=> 
    [b.family_name_kana.tr(origin, normalize), b.first_name_kana.tr(origin, normalize)]
  }

よりも

  users.sort_by{|a| [a.family_name_kana.tr(origin, normalize), a.first_name_kana.tr(origin, normalize)]}

の方がムダがなくて良かった。


  • trについても一応説明

class String参照。

tr(search, replace)、tr!(search, replace)
  文字列の中に search 文字列に含まれる文字が存在したら、それを replace 文字列の対応する文字に置き換える。
  search の形式は tr(1) と同じ。つまり、 `a-c' は a から c を意味し、"^0-9" のように文字列の先頭が `^' の場合は指定文字以外が置換の対象になる。
  replace に対しても `-' による範囲指定が可能。
  `-' は文字列の両端にない場合にだけ範囲指定の意味になる。同様に、`^' もその効果は文字列の先頭にあるときだけ。
  また、 `-', `^', `\' はバックスラッシュ(`\')によりエスケープすることができる。
  replace の範囲が search の範囲よりも小さい場合は、 replace の最後の文字が無限に続くものとして扱われる。
  tr は置換後の文字列を生成して返す。 tr! は self を変更して返すが、置換が起こらなかった場合は nil を返す。

  • 余談

因みに、最初、

(family_name_kana+first_name_kana).tr(origin,normalize)

でsortをした方がシンプルだなぁと思ってそうしていたら、「わたなべ ほげほげ」さんと「わだ ふがふが」さんの順番がわださんが後になってしまっていた。苗字と名前をつなげちゃだめだった。


お読み頂きありがとうございます。

少しでもお役に立てたらクリックお願いします↓。

にほんブログ村 IT技術ブログ プログラム・プログラマへ人気ブログランキングへ Subscribe with livedoor Reader

◆◆このブログのサイトマップへ◆◆

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

 |