PHPマニュアルにあるusortの説明がうまく理解できなくて悩んでいます。
そこでは、パラメータとなる比較関数について次のように書かれています。
「比較関数は、最初の引数と二番目の引数の比較結果を返します。最初の引数のほうが二番目の引数より大きい場合は正の数を、二番目の引数と等しい場合はゼロを、そして二番目の引数より小さい場合は負の数を返す必要があります。」
http://php.net/manual/ja/function.usort.php
「usort() の例」として提示されているのは以下です。
function cmp($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
$a = array(3, 2, 5, 6, 1);
usort($a, "cmp");
この例のユーザー定義の比較関数cmpは、前述の説明の通りに書かれているので理解できます。
しかし、ユーザーページの投稿にもありますが、($a > $b) としたり、($a < $b) ? 1 : -1 のように返り
値を変えて降順(逆順)にソートするという使い方を普通に見かけます。
これは、「最初の引数のほうが二番目の引数より大きい場合は正の数を(……)二番目の引数より小さい場合は負の数を返す必要があ」るという説明とは矛盾しています。
「必要」とまで書いているのでかなり強い指示だと思います。英語版でも「must」となっているので翻訳上の問題はなさそうです。
また、「配列のソート」ページによるとソート順は「ユーザー定義」とあり、件の比較関数次第ということになっています。
http://www.php.net/manual/ja/array.sorting.php
ということは、逆順であれ自然順であれ可能だとこれは示唆しているのだと思うのですが、やはり説明部分との矛盾が気になります。
……どう捉えたらよいのでしょうか?
No.3ベストアンサー
- 回答日時:
「最初の引数のほうが二番目の引数より大きい場合は正の数を(……)二番目の引数より小さい場合は負の数を返す必要がある」
↓
「配列の中から任意に2要素$a,$b(但し$aの方がかならず左にある)を取り出したとき、$aと$bを入れ替える必要があれば正の数を、入れ替える必要が無ければ負の数を返す必要がある」
と置き換えて考えてください。
(実際には等しい場合は0を返したほうがソートの効率がよくなると思われます)
こちらのC言語のバブルソートのプログラムをご覧ください。
http://www1.cts.ne.jp/~clab/hsample/Sort/Sort1.h …
if (x[j - 1] > x[j]) { /* 前の要素の方が大きかったら */
この行を
if (cmp_function(a, b)) { /* 前の要素の方が大きかったら */
に置き換えるのがusort関数と考えると分かりやすいですかね?
(実際にPHPが行っているのはバブルソートではなく、クイックソート・マージソートなどの併用ソートですが)
No.4
- 回答日時:
一番目の引数の値は、2、 二番目の引数の値は、5 だったとして、
2と5、あなた決めたルールでは、どちらを大きいとしますか?
数字なら5の方が大きいでしょう、では、数字ではなくコードだとしたら?
あなたの作成するプログラムでは、
コードの2は、ドラゴン、
コードの5は、スライムかもしれません。
モンスターの名前順、レベル順、攻撃力順、
あるいは、モンスターの名前の逆順、レベルの逆順、攻撃力の逆順
モンスターの名前順なら、「あ」が一番小さく、「ん」が一番大きいとして
名前の逆順なら、「ん」が一番小さく、「あ」が一番大きい値です。
レベル順なら、レベル1が一番小さく、レベル99が一番大きい値です
レベル逆順は、レベル99が一番小さな値で、レベル1が一番大きな値です
そもそも、
数字の2と5を比較して5の方が大きいから負の数を返すなら、この関数の存在意義が無いですよね
No.5
- 回答日時:
データの大小と、順列番号の大小は別 なのですが、質問者さんの引っかかってる「must」については、日本語の語順に惑わされてるようです。
must return an integer は、返値は、Integer型で返す必要があるの意味。
引数比較については considered to be respectively なので、どっちを大きい(順列の後方)と考えるかによって返値を調整しろということ。「必ず大きい方」ではない。
日本語にすると語順的にどこに「必要」がかかってるか解りにくいのが欠点ではある。ていうか「整数」が抜けてるせいか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- PHP PHP MySql ページング 2 2022/09/20 06:38
- 数学 モデルのパラメータの定義がいまいちわかりません。 3 2022/10/11 15:16
- Visual Basic(VBA) Excel のユーザー定義関数でソルバーが動作しない 1 2022/09/05 19:51
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# 関数ポインタの高速化のメリット 7 2023/05/05 20:15
- その他(ビジネススキル・経営ノウハウ) 在庫管理のこの問題が分かりません。どなたか解説お願いします 2 2022/04/18 18:35
- 数学 在庫管理のこの問題が分かりません。どなたか解説お願いします 4 2022/04/18 22:19
- 数学 在庫管理のこの問題が分かりません。どなたか解説お願いします 2 2022/04/18 22:21
- Ruby 初心者プログラミング 3 2022/10/12 11:31
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
配列をループでたくさん宣言し...
-
file_existsでファイル名の部分...
-
foreachのなかで次のキーを参照...
-
PHPで多次元配列を一度に処理す...
-
チェックボックス複数選択 mys...
-
mb_ereg_replaceについて
-
前のページで入力したものをあ...
-
プルダウンメニューでCSVデータ...
-
重複しないランダム関数を教え...
-
PHPで配列をPOSTデータで送った...
-
PHPのループ数限界値について
-
Smarty の演算方法
-
配列の書き方
-
PHPのカッコ[ ]の使い方について
-
プログラミングのPythonのnoteb...
-
スカラーのベクトル微分
-
PHPでこのコード自体に意味は無...
-
ヒアドキュメントの中のfor文
-
連想配列のキー値(連番)を基...
-
Excel VBAでフィルター後の対象...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
配列をループでたくさん宣言し...
-
file_existsでファイル名の部分...
-
$_SESSIONに二次元配列を使える...
-
foreachのなかで次のキーを参照...
-
String だと「 ByRef引数の型が...
-
配列を回すとき、最後の要素だ...
-
配列一致(要素順番は違うが内容...
-
PHPのカッコ[ ]の使い方について
-
ネストが深い時のforeachはどう...
-
チェックボックス複数選択 mys...
-
PHPで配列をPOSTデータで送った...
-
phpで、連想配列を普通の配列に...
-
PHP 多次元配列変数のデータ受...
-
postgresql関数をつかったレコ...
-
【PHP】配列内のある値以上をカ...
-
SQL文の実行結果を変数で受けて...
-
プルダウンメニューでCSVデータ...
-
Smartyのテンプレートからjavas...
-
PHPにてクラスを配列にすること...
-
CSVデータのn番目だけの値を取...
おすすめ情報