読者です 読者をやめる 読者になる 読者になる

アナログCPU:5108843109

ゲームと音楽とプログラミング(酒と女とロックンロールのノリで)

文字列の集合をインデックスごとに分ける方法

PHP 文字列処理

「あいす」→あ行
「ほげ」→は行
…のような感じで、頭文字からインデックスの文字を求める方法のことですね。

どうすればいいかはまあ分かりますけど、
もっと画期的な方法はないかなーと思いつつググってみたら、こんなQ&Aがありました。
oshiete.goo.ne.jp
別に画期的でもなんでもないというか、考えてたのと変わらんというか、やっぱこうなるかって感じです。

3つの回答がありますが、これらをちょっと拝借して、単純化したものを以下に記載してみます。

<凡例>
 $index_list(_*):50音とインデックス文字の定義配列
 $initial:単語の頭文字
 $index_char:単語のインデックス文字 ←これを求めたい

① 50音すべてに対してインデックス文字を定義する方法

$index_list_base = array(
    "あいうえお",
    "かきくけこがぎぐげご",
    // …
    "わをん",
);
// ↑を元に、↓の配列を生成する(詳細は省略)
$index_list = array(
    "あ" => "あ",
    "い" => "あ",
    "う" => "あ",
    // …
    "か" => "か",
    "き" => "か",
    "く" => "か",
    // …
    "ん" => "わ",
);

$index_char = $index_list[$initial];

② インデックス文字に対して正規表現を定義する方法

$index_list = array(
    "あ" => "[あ-お]",
    "か" => "[か-こが-ご]",
    // …
    "わ" => "[わ-ん]",
);

foreach ($index_list as $key => $index)
{
    if ($initial が正規表現 $index にマッチ)
    {
        $index_char = $key;
        break;
    }
}

③ 頭文字をインデックス文字にreplaceする方法

$index_list_of = array(
    "あ","い","う","え","お",
    "か","き","く","け","こ","が","ぎ","ぐ","げ","ご",
    // …
    "わ","を","ん",
);
$index_list_by = array(
    "あ","あ","あ","あ","あ",
    "か","か","か","か","か","か","か","か","か","か",
    // …
    "わ","わ","わ",
);

$index_char = str_replace($replace_of, $replace_by, $initial);

どれが良いかは好みが分かれそうなところですね。

①は定義部分が最小限(ただし重い)、インデックス文字を求めるのは最速
②は定義部分が比較的シンプルだが、インデックス文字を求める際に繰り返し処理が発生
③は定義部分が多め、インデックス文字を求める際に繰り返しはないが文字置換を行う

やらなくてもいい繰り返し処理や文字置換はできれば省きたいので、
①を参考に元々考えてたやつをちょっと変えて、こんな感じにしてみました。

④ 50音すべてに対してインデックス文字を定義する方法・改

$index_list = array(
    "あ" => "あ", "い" => "あ", "う" => "あ", "え" => "あ", "お" => "あ",
    "か" => "か", "き" => "か", "く" => "か", "け" => "か", "こ" => "か", "が" => "か", "ぎ" => "か", "ぐ" => "か",  "げ" => "か",  "ご" => "か",
    // …
    "わ" => "わ", "を" => "わ", "ん" => "わ",
);
$index_char = $index_list[$initial];

①は定義部分はシンプルですが、毎回毎回foreach×for回すのかよ! というのがツッコミどころですね。
それを最初からベタ書きで定義したのがこの④です。
定義がきったねぇんですが、パッと見てベタ書き定義だと分かるので、少々横長かろうが許されやすいかなと…。

まあ、①にしろ④にしろ、この形の配列を作ってしまえば、あとは簡単にインデックス文字を取得できるので、大変シンプルな挙動で済ませることができます。