usortでハマった件(繰り上げと繰り下げの怪)

日々雑感

PHPのusortについて。
基本的な機能はマニュアルで確認していただくとして…
https://www.php.net/manual/ja/function.usort.php

「ユーザー定義の比較関数を使用して、配列を値でソートする」ことができる関数なわけですが、この比較関数の使い方が最初はなかなかとっつきにくい。

そこで検索すると上位に出てくる解説記事があり、基本的にとても丁寧に書いてくださっているのですが、日本語の微妙な表現にハマりました。

それは「繰り上げる」「繰り下げる」という言葉で、用意した比較関数の返り値として
「$aと$bを比較し、-1を返すと$aの順番を$bより繰り下げる」
「$aと$bを比較し、1を返すと$aの順番を$bより繰り上げる」
(0を返すと変更なし)
というように書いてあるので、例えば
[0 => ‘a’, 1 => ‘b’, 2 => ‘c’]
という配列で、最初(Keyが0の値)と次(Keyが1の値)を比較した時、比較関数が-1を返すと
[0 => ‘b’, 1 => ‘a’, 2 => ‘c’]
1を返すと
[0 => ‘a’, 1 => ‘b’, 2 => ‘c’](既にaがbより手前なのでそのまま変更なし)
という結果をイメージしました。

でも実際は逆で、
比較関数が-1を返すと
[0 => ‘a’, 1 => ‘b’, 2 => ‘c’](この場合は変更なし)
1を返すと
[0 => ‘b’, 1 => ‘a’, 2 => ‘c’]
となります。

…ハマりました。
シンプルな例でテストしていればすぐ気づけたのでしょうが、別の条件式とも絡んでいたため、なかなか気づけず…。

おそらく解説者の方にとって「繰り上げる」という言葉が「よりKeyが大きな値の方へずらす(数値の場合)」、「繰り下げる」という言葉は「よりKeyが小さな値の方へずらす(数値の場合)」というイメージだったのかな、と後で思いましたが、参考にされたほかのみなさんはどうだったんでしょうねぇ…(もちろん解説記事自体はとてもありがたく、いつもお世話になっております)。