昔、PHPのusort関数がきもかったのに、今はそうでもない。

PHPを触り始めて間もない頃、何かの理由でusort関数を使ったか使ってないか、
とにかくusort関数とは何ぞや?と調べて動かしてみた事がある。

マニュアルのサンプルソースはこんな感じ...

<?php
function cmp($a, $b)
{
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

$a = array(3, 2, 5, 6, 1);

usort($a, "cmp");

「この関数は、ユーザー定義の比較関数により配列をその値でソートします。 」

面食らったのは比較関数の引数「$a, $b」、何これ?
自分で $result = cmp( "なんか", "なんぞ" ); って呼んだ覚えが無いのに?

「比較関数は、最初の引数が 2 番目の引数より小さいか、等しいか、大きい場合に、 それぞれゼロ未満、ゼロに等しい、ゼロより大きい整数を返す 必要があります。 」

要するに、等しければ0、そうでなければ大小に応じて-1か1を返す、
うん、それは分かった。実際やってみたし、出来たよ。
しかしreturnした値は誰が受け取ってるの?

もう一つ違和感があったのはユーザ定義関数"cmp"をusort($a, "cmp")と引数で関数名を渡すなんて、なんすかこれ?
マニュアルを見ると「コールバック関数」だと。そしてググる

コールバック関数とは
http://ew.hitachi-system.co.jp/w/E382B3E383BCE383ABE38390E38383E382AFE996A2E695B0.html

こんな一文が書いてある...

「電話を相手に一度かけて電話番号のみを伝え、いったん電話を切って折り返し相手からかけなおしてもらう様子(これを「コールバック」という)に似ているためこの名前がついた。」


他のサイトでも大体この電話のくだりが書いてあり、電話、電話、電話、頭の中は電話のシーンが回るばかり。
要するに「コールバック関数」がピンとこない。

結局
・引数と「$a,$b」ってなに?
・戻り値は誰が受け取ってるの?
・コールバック関数ってなに?
これらがよく分からないまま月日が流れる。


その後、オブジェクトとかクラスとかも何となく理解でき、wordpressを弄ったり、CakePHPをやりだしたりしてるうちに
なんとなく分かってきた。分かってしまうと逆に説明が出来ないw
「引数と戻り値はPHPの中の人が用意したり、使ったりしてる。」としか言い様が無いw


参考:いろいろなソートアルゴリズム

ソートのアルゴリズムは色々あるらしいが、順番はどうあれ、値と値を比較するのはどれも一緒。
cmp関数が(どんな順番か知らんけど)PHPの中の人から何回も呼ばれ、ある値とある値を比較して結果を返す。

PHPさんが言うには、
「あんたの作った関数の引数で値を二つ渡すから、0か-1か1で返事をしてくれ。」
「あんたがどんな方法で比較しようが知ったこっちゃねぇ。あんたの返事に従ってソートさせて貰う。」
だそうです。

コールバック関数については色々な説明の仕方があると思うけど、
usort関数の場合「比較には"cmp"って関数を使って下さい」と指定しているだけのこと。

分かってしまうとこんな説明になるけど、
「分からなかった過去の自分」がこの記事読んでも分からんだろうな。

以下は何となく作ってみた例
pointでソートする。

<?php

function sort_by_point( $a, $b )
{
    if ($a['point'] == $b['point']) {
        return 0;
    }
    return ($a['point'] < $b['point']) ? -1 : 1;
}


$sample = array(
	array( 'id' => 1, 'name' => "hoge", 'point' => 30 ),
	array( 'id' => 2, 'name' => "fuga", 'point' => 10 ),
	array( 'id' => 3, 'name' => "piyo", 'point' => 20 ),
);

usort($sample, "sort_by_point");

echo "<pre>";
print_r( $sample );
echo "</pre>";

?>