お知らせ

【脱初心者】【PHP】便利な関数usort()の使い方とメリット・デメリットを解説 

PHP

どうも、こんにちは!ピコっそです。
前回の記事では、PHPの「宇宙船演算子(<=>)」を紹介しましたが、その中で登場したカスタムソート関数 「usort()」 に興味を持った方も多いのではないでしょうか。

今回はその usort()関数の使い方や、メリット・デメリット をわかりやすく解説していきます。
配列を自由に並び替えたいときに役立つ、とても強力な関数です。

なお、宇宙船演算子について詳しく知りたい方は、ぜひ以下の記事もチェックしてみてください👇

usort()とは

usort()とはカスタムソート関数のうちの一つで、

自分でルールを決めて配列を並び替える

役割をもつ関数です。

通常の sort() や rsort() のような関数では、単純な昇順・降順しか行えませんが、
usort() を使えば「どの値を基準に」「どんな順で」並べるかを自由に指定できます。

基本構文は以下のとおりです。

usort(配列, 比較関数);

usortの引数は二つあり、一つ目は並べ替えたい配列を用意し、二つ目はどのように並べるか定義した比較関数を入れる必要があります。

そして、このusort()は前回紹介した宇宙船演算子と非常に相性がよく、比較関数の中で使うことで、たった1行でソート条件を書けるようになります。

実例を見てみよう

usort()を使ったコードを実際に見てみましょう。

$students = [
            ["name" => "佐藤", "score" => 75],
            ["name" => "鈴木", "score" => 52],
            ["name" => "田中", "score" => 93],
            ["name" => "高橋", "score" => 68],
            ["name" => "伊藤", "score" => 48]
        ];

// 比較関数を定義(宇宙船演算子を使い、スコアを降順に並べ替える)
function sort_student($a, $b){
    return $b["score"]<=>$a["score"];
}

// usortを実行:配列をカスタムルールで並び替える
usort($students, "sort_student");

// 並び替えた結果を出力
foreach ($students as $student) {
    echo $student["name"].':'.$student["score"].'<br>';
}

コードの意味:

多次元配列の中にある”score”を降順に並べて、出力するコード

各コードの意味:

1:多次元配列 $students
→各要素が「名前」と「点数」を持つ小さな配列になっています。

2:比較関数 sort_student()
→ 宇宙船演算子 <=> を用いて、点数の高い順(降順)に並べるルールを定義。

3:usort() 関数

→ 定義したルールを使って、配列全体を並び替え。

4:出力部分

→ 並び替え後の結果を1行ずつ表示。

出力した結果は、

田中:93
佐藤:75
高橋:68
鈴木:52
伊藤:48

上記の通りになります。

ポイント

・宇宙船演算子(<=>)をつかうと、わずか1行で比較関数を書くことができる

・usortを使って「自由に値を並べ替えることができる」こと

・昇順にしたい場合は、単に $a[“score”] <=> $b[“score”] にすればOK!

usortを使うメリット

続いてusortを使うメリットについて解説します。メリットは主に3つあります。

① 並び替えのルールを「自由に定義」できる

sort() は単純に昇順や降順しかできませんが、
usort() なら「点数の高い順」「名前の長い順」「日付の新しい順」「複数条件でのソート」など、完全に自分仕様のルールで並び替えが可能です。

// 名前の文字数が長い順に並び替える
usort($students, function($a, $b){
    return strlen($b["name"]) <=> strlen($a["name"]);
});

「名前の長さ」という独自ルールでソートできるのは usort() の強み!

② 比較関数を使って「複数条件のソート」ができる

単一の値(例:スコア)だけでなく、
スコアが同じ場合は名前順などの「複合条件ソート」も簡単に実装できます。

usort($students, function($a, $b){
    // まずスコアで比較、同点なら名前で比較
    return $b["score"] <=> $a["score"] ?: $a["name"] <=> $b["name"];
});

→ これで「点数が同じ人は名前順で並ぶ」ようにできる。

③ コードをシンプルに書ける(宇宙船演算子との相性◎)

usort() は function や無名関数(クロージャ)と組み合わせることで、わずか1行でルールを定義できる。特に <=>(宇宙船演算子)を使えば、複雑な if 文を書かずに済む。

usort($students, fn($a, $b) => $b["score"] <=> $a["score"]);

→ たったこれだけで「スコアの高い順」完成。
→ 見た目もすっきり、メンテもしやすい。

このように、usortを使うことによって、自由に並び替えのルールが定義することができ、かつシンプルに書けるので、応用の効かせたコーディングをすることも可能になると言う強みがあります。

usortを使うデメリット

続いてusortを使う際のデメリットについても解説します。デメリットも主に3つあります。

特に三つ目は私も最初は戸惑ったところですので、よく確認することをお勧めします

① 元の配列が上書きされる(破壊的ソート)

usort() は配列を直接並び替える関数なので、ソート前の順番は失われます。

$students_copy = $students; // コピーしておくと安全
usort($students, 'sort_student');

➡ 対策: 元の順番を残したい場合は、コピーを作ってから usort() を使うようにしましょう。

② 連想配列の「キー」が失われる

usort() は配列の値のみを並び替えるため、連想配列のキー(例:id や user_1)は保持されません。

<code>
$users = [
    "user1" => ["score" => 90],
    "user2" => ["score" => 70]
];
usort($users, fn($a, $b) => $b["score"] <=> $a["score"]);
print_r($users);
</code>

→ 出力結果では “user1”, “user2” のキーが消えて、[0], [1] のような数値インデックスになります。

➡ 対策: キーを保持したい場合は uasort() を使うと良いです。uasort()について詳しく知りたい方は以下の記事からチェックしてみてください。

③ 比較関数の書き方を間違えると意図しない並びになる

usort() は比較関数の戻り値(正・負・0)に依存するため、比較条件を間違えると逆順やランダム順になることがあります。

return $a["score"] > $b["score"]; // ❌ true/falseを返してしまう

これだと 1 や 0 が返り、安定しない結果になります。

➡ 対策: 必ず <=>(宇宙船演算子)を使うか、
return ($a[“score”] < $b[“score”]) ? -1 : 1; のように明示的に返す。

上記3点から、usort()を使う際には必ずもとデータを保存したうえで正しく関数を定義する必要があり、すこし中級者向けな感じもします。

このように、便利な一方で、細かい仕様を理解して使うことで usort() の真価が発揮されると私は思います。

まとめ

今回は、前回の宇宙船演算子に続いて、usort()の使い方やメリット・デメリットの解説の方を行いました。usort()は自分で決めたルールのもと、並び替えを自由に行える便利な関数です。

usort()を使うメリットとデメリットは以下のとおりです。

メリットデメリット
並び替えのルールを「自由に定義」できる元の配列が上書きされる
「複数条件のソート」ができる連想配列の「キー」が失われる
コードをシンプルに書ける比較関数の書き方を間違えると意図しない並びになる

このように、usrot()は扱いが非常に難しい関数であるものの、使い方を理解すれば、真価を発揮できる便利な関数であると考えます。

最後に

今回の記事でusort()の使い方がわかった人が一人でもいれば嬉しいと思います。特に今回の記事の内容はかなり難易度が高かったので、理解するのに時間がかかった人も多いかもしれません。

次回は、uasort()の使い方についての解説記事を出します。

よかったらまた見にきてくださいね。

では最後までご覧いただき、ありがとうございました。

今後も初心者でも理解しやすいJavaScript・PHPの基礎シリーズを投稿していきます!

どうぞよろしくお願いいたします。

コメント

タイトルとURLをコピーしました