PHP開発者のためのusort | 配列を自分のルールでソートする方法

ソートは、プログラミングにおいて基本的かつ頻繁に使用される操作の一つです。PHPでは、組み込みのソート関数(例えばsortasort)が提供されていますが、時には正直多すぎてどれを使えば良いのか分かりづらいのが多々あります。

どれを使えば良いのか、このコードは何ソートなのか。
kやrで省略されて表示されているのも混乱の要因です。
https://www.php.net/manual/ja/array.sorting.php

そこで登場するのが、PHPの強力なツールの一つであるusort関数です。

usortを使えば、配列内の要素を独自のルールでソートすることができます。

これは、特定の要因に基づいたカスタムソートや、複雑な比較ロジックが必要な場合、特に何を基準にしたソートなのかが解るように記述することができます。以下が usortを使う利点になります。

  1. 複雑なソート要件の対応
    • 組み込みのソート関数では対応できない複雑なソート要件や、複数の要因に基づくソートが必要な場合に、usortは非常に役立ちます。
  2. 読みやすさ
    • 自分で作成したカスタム比較関数を使用するので、ソートのロジックが明確になります。
  3. 柔軟性
    • usortを使用することで、異なるデータ型の配列やオブジェクトの配列をソートできます。組み込みのソート関数は、基本的に単純な比較に限定されています。

本記事では、usortの使い方を詳しく解説し、あなたが独自のソートロジックを実装し、PHPの配列を自在に操る手助けをします。

usort関数の使い方

usort関数の構文は次の通りです。

usort(array &$array, callable $callback): true

callback(mixed $a, mixed $b): int

第1引数に配列を渡しますが参照渡しになっているのでソート結果で上書きされます。

第2引数に比較関数を指定することでソート内容を記述することができます。

注意点としてはusort関数は実行結果で新しくキーを振り直すのと、callbackの返却値はintしか対応していないのでfloatを返却してしまうとソートが上手くいかない点にあります。

実際に使用したサンプルコードはこちらになります。

<?php

$numbers = [5, 2, 9, 3, 6];

// カスタム比較関数を定義
function customCompare($a, $b) {
    if ($a == $b) {
        return 0;
    }
    return ($a > $b) ? -1 : 1;
}

usort($numbers, 'customCompare');
print_r($numbers);
/**
Array
(
    [0] => 9
    [1] => 6
    [2] => 5
    [3] => 3
    [4] => 2
)
 */


// クロージャー
usort($numbers, function ($a, $b) {
    return $a - $b;
});
print_r($numbers);

/**
Array
(
    [0] => 2
    [1] => 3
    [2] => 5
    [3] => 6
    [4] => 9
)
 */


// keyは保持されない
$array = [
  'one' => 1,
  'two' => 2,
  'three' => 3,
];

usort($array, function ($a, $b) {
    return $a - $b;
});
print_r($array);

/**
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)
 */

// callbackにfloatを返却するとソートできない
$floats = [1.2, 3.4, 3.6, 3.9, 3.1];
usort($floats, function ($a, $b) {
    return $a - $b;
});
print_r($floats);
/**
Array
(
    [0] => 1.2
    [1] => 3.4
    [2] => 3.6
    [3] => 3.9
    [4] => 3.1
)
 */

// floatでもソートできる方法
usort($floats, function ($a, $b) {
    if ($a == $b) {
        return 0;
    }
    return ($a > $b) ? 1 : -1;
});
print_r($floats);
/**
Array
(
    [0] => 1.2
    [1] => 3.1
    [2] => 3.4
    [3] => 3.6
    [4] => 3.9
)
 */


// 多次元配列
$array = [
  ['num' => 10],
  ['num' => 1],
  ['num' => 4],
];

usort($array, function ($a, $b) {
    return $a['num'] - $b['num'];
});
print_r($array);

/**
Array
(
    [0] => Array
        (
            [num] => 1
        )

    [1] => Array
        (
            [num] => 4
        )

    [2] => Array
        (
            [num] => 10
        )

)
 */

上記の結果でusortの実行方法がわかるかと思います。

前述の注意点通り、キーは振り直されます。

キーの振り直しをしたくない場合は uasort()、キーを基準にしたソートでは uksort()の使用が推奨されます。

落とし穴としてはcallbackには整数しか対応していなく、浮動小数点になってしまうと自動的に整数にキャストされてしまうためソートができなくなります。

浮動小数点が入る可能性がある場合にはif文でどちらが大きいかを確認するようにしましょう。

最後に

以上、PHPのusort関数の使い方について解説してきました。

PHPの配列周りの標準関数はとても多く、sort関連も多く用意されています。これらを暗記するよりも、usort関数を使いこなすことで上手にソートできるようにした方が柔軟性も高まります。

この記事を読んでいるあなたのプロジェクトに活用できましたら幸いです。

お疲れ様でした。