昔、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>"; ?>