usort

(PHP 4, PHP 5, PHP 7, PHP 8)

usortユーザー定義の比較関数を使用して、配列を値でソートする

説明

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

順序を決めるユーザー定義の比較関数により、 array をその値でソートします。

注意:

比較結果が等しくなる二つの要素があった場合、それらの並び順は保持されます。PHP 8.0.0 より前のバージョンでは、ソートした配列におけるそれらの並び順は不定でした。

注意: この関数は、 array パラメータの要素に対して新しいキーを割り当てます。 その際、単純にキーを並べ替える代わりに、 すでに割り当てられている既存のキーを削除してしまいます。

パラメータ

array

入力の配列。

callback

比較関数は、最初の引数と二番目の引数の比較結果を返します。最初の引数のほうが二番目の引数より大きい場合は正の整数を、二番目の引数と等しい場合はゼロを、そして二番目の引数より小さい場合は負の整数を返す必要があります。

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

float のような 非整数 を比較関数が返すと、その返り値を内部的に int にキャストして使います。 つまり、0.990.1 といった値は整数値 0 にキャストされ、 値が等しいとみなされます。

戻り値

常に true を返します。

変更履歴

バージョン説明
8.2.0 戻り値の型が、true になりました。これより前のバージョンでは、bool でした。
8.0.0callback がリファレンス渡しされる引数を期待している場合、 この関数は E_WARNING を発生させるようになりました。

例1 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");

foreach (
$a as $key => $value) {
echo
"$key: $value\n";
}
?>

上の例の出力は以下となります。

0: 1 1: 2 2: 3 3: 5 4: 6

内部的な比較をさらにシンプルにするために、 宇宙船演算子を使うこともできます。

<?php
function cmp($a, $b)
{
return
$a <=> $b;
}

$a = array(3, 2, 5, 6, 1);

usort($a, "cmp");

foreach (
$a as $key => $value) {
echo
"$key: $value\n";
}
?>

注意:

もちろん、このような簡単な例では rsort() 関数の方がより適当です。

例2 多次元配列を使用する usort() の例

<?php
function cmp($a, $b)
{
return
strcmp($a["fruit"], $b["fruit"]);
}

$fruits[0]["fruit"] = "lemons";
$fruits[1]["fruit"] = "apples";
$fruits[2]["fruit"] = "grapes";

usort($fruits, "cmp");

foreach (
$fruits as $key => $value) {
echo
"\$fruits[$key]: " . $value["fruit"] . "\n";
}
?>

多次元配列をソートする際には、$a$b は配列の最初のインデックスへの参照を保持しています。

上の例の出力は以下となります。

$fruits[0]: apples $fruits[1]: grapes $fruits[2]: lemons

例3 usort() でオブジェクトのメンバ関数を使用する例

<?php
class TestObj {
private
string $name;

function
__construct($name)
{
$this->name = $name;
}


static function cmp_obj($a, $b)
{
return
strtolower($a->name) <=> strtolower($b->name);
}
}

$a[] = new TestObj("c");
$a[] = new TestObj("b");
$a[] = new TestObj("d");

usort($a, [TestObj::class, "cmp_obj"]);

foreach (
$a as $item) {
echo
$item->name . "\n";
}
?>

上の例の出力は以下となります。

b c d

例4 usort()クロージャ を使って多次元配列をソートする例

<?php
$array
[0] = array('key_a' => 'z', 'key_b' => 'c');
$array[1] = array('key_a' => 'x', 'key_b' => 'b');
$array[2] = array('key_a' => 'y', 'key_b' => 'a');

function
build_sorter($key) {
return function (
$a, $b) use ($key) {
return
strnatcmp($a[$key], $b[$key]);
};
}

usort($array, build_sorter('key_b'));

foreach (
$array as $item) {
echo
$item['key_a'] . ', ' . $item['key_b'] . "\n";
}
?>

上の例の出力は以下となります。

y, a x, b z, c

例5 usort() と宇宙船演算子

宇宙船演算子は、 複数の軸をまたがった複合的な値を明快に比較する用途に使えます。 以下の例は、$people を last name で比較し、 それが一致するものについては first name で比較します。

<?php
$people
[0] = ['first' => 'Adam', 'last' => 'West'];
$people[1] = ['first' => 'Alec', 'last' => 'Baldwin'];
$people[2] = ['first' => 'Adam', 'last' => 'Baldwin'];

function
sorter(array $a, array $b) {
return [
$a['last'], $a['first']] <=> [$b['last'], $b['first']];
}

usort($people, 'sorter');

foreach (
$people as $person) {
print
$person['last'] . ', ' . $person['first'] . PHP_EOL;
}
?>

上の例の出力は以下となります。

Baldwin, Adam Baldwin, Alec West, Adam

参考

  • uasort() - ユーザー定義の比較関数で配列をソートし、連想インデックスを保持する
  • uksort() - ユーザー定義の比較関数を用いて、キーで配列をソートする
  • 配列ソート関数の比較
To Top