はてなブログの記事の五十音順タイトル一覧を作る

はてなブログの記事の五十音順タイトル一覧を作る

はてなブログのタイトルにふりがなを振り、php 配列に格納するの続きです。

タイトルにふりがなが付きましたので、ふりがなでソートして書き出せばいいのですが、インデックスをどうするかです。450記事もありますと「あ行」「か行」では1ブロックが多くなりそうですので、五十音すべてのインデックスをつけようと思います。

五十音インデックスのつけかた

どうやるのが効率的なのか、とにかく方法を考えましょう。やるべきことは、

  • ふりがなの最初の1文字を取り出し五十音でグループ化する
  • グループごとにふりがなでソートする
  • 濁音、半濁音、「ヴ」の処理も必要

難しいですね。

思いついたのは、五十音のインデックスを配列で作り、各タイトルのひらがな1文字と比較してグループ化していく方法です。インデックスは、

$indexes = array(
    "数字" => "[0-9]", "英字" => "[a-zA-Z]",
    "あ" => "[あ]", "い" => "[い]", "う" => "[うヴ]", "え" => "[え]", "お" => "[お]",
    "か" => "[かが]", "き" => "[きぎ]", "く" => "[くぐ]", "け" => "[けげ]", "こ" => "[こご]",
    "さ" => "[さざ]", "し" => "[しじ]", "す" => "[すず]", "せ" => "[せぜ]", "そ" => "[そぞ]",
    "た" => "[ただ]", "ち" => "[ちぢ]", "つ" => "[つづ]", "て" => "[てで]", "と" => "[とど]",
    "な" => "[な]", "に" => "[に]", "ぬ" => "[ぬ]", "ね" => "[ね]", "の" => "[の]",
    "は" => "[はばぱ]", "ひ" => "[ひびぴ]", "ふ" => "[ふぶぷ]", "へ" => "[へべぺ]", "ほ" => "[ほぼぽ]",
    "ま" => "[ま]", "み" => "[み]", "む" => "[む]", "め" => "[め]", "も" => "[も]",
    "や" => "[や]", "ゆ" => "[ゆ]", "よ" => "[よ]",
    "ら" => "[ら]", "り" => "[り]", "る" => "[る]", "れ" => "[れ]", "ろ" => "[ろ]",
    "わ" => "[わ]", "ん" => "[ん]",
    "その他" => ".*"
);

これでやってみましょう。

五十音で並べ替え、インデックスごとに配列に格納する

<?php
// 前回作った配列を読み込む
$orgArray = unserialize(file_get_contents('movies.txt'));
// 五十音インデックス
$indexes = array(
    "数字" => "[0-9]", "英字" => "[a-zA-Z]",
    "" => "[あ]", "" => "[い]", "" => "[うヴ]", "" => "[え]", "" => "[お]",
    "" => "[かが]", "" => "[きぎ]", "" => "[くぐ]", "" => "[けげ]", "" => "[こご]",
    "" => "[さざ]", "" => "[しじ]", "" => "[すず]", "" => "[せぜ]", "" => "[そぞ]",
    "" => "[ただ]", "" => "[ちぢ]", "" => "[つづ]", "" => "[てで]", "" => "[とど]",
    "" => "[な]", "" => "[に]", "" => "[ぬ]", "" => "[ね]", "" => "[の]",
    "" => "[はばぱ]", "" => "[ひびぴ]", "" => "[ふぶぷ]", "" => "[へべぺ]", "" => "[ほぼぽ]",
    "" => "[ま]", "" => "[み]", "" => "[む]", "" => "[め]", "" => "[も]",
    "" => "[や]", "" => "[ゆ]", "" => "[よ]",
    "" => "[ら]", "" => "[り]", "" => "[る]", "" => "[れ]", "" => "[ろ]",
    "" => "[わ]", "" => "[ん]",
    "その他" => ".*"
);
// 先に並べ替えたほうがよさそう
$tmpArray = array();
foreach ( $orgArray as $key => $val ) {
    $tmpArray[$key] = $val['ruby'];
}
array_multisort( $tmpArray, SORT_ASC, $orgArray );
// インデックスごとの配列に格納する
$movies = array();
foreach ( $orgArray as $key => $val) {
    $char = mb_substr( $val['ruby'], 0, 1);
    foreach ( $indexes as $index => $pattern ) {
        if (preg_match("/^" . $pattern . "/u", $char)) {
            $movies[$index][] = $orgArray[$key];
            break;
        }
    }
}
// html に書き出す
$html = '';
foreach ($movies as $index => $movie) {
    $html .= '<h3>' . $index . '</h3>';
    $html .= '<ul>';
    foreach ($movie as $key => $val) {
        $html .= '<li><a href="' . $val['url'] . '">' . $val['title'] . '</a></li>';
    }
    $html .= '</ul>';
}
echo $html;

出力

うまくいきました!