|
usort
ユーザー定義の比較関数を使用して、配列を値でソートする
説明
true usort(array &$array , callable $callback )
注意:
比較結果が等しくなる二つの要素があった場合、それらの並び順は保持されます。PHP 8.0.0 より前のバージョンでは、ソートした配列におけるそれらの並び順は不定でした。
注意: この関数は、
array パラメータの要素に対して新しいキーを割り当てます。
その際、単純にキーを並べ替える代わりに、
すでに割り当てられている既存のキーを削除してしまいます。
パラメータ
-
array
-
入力の配列。
-
callback
-
比較関数は、最初の引数と二番目の引数の比較結果を返します。最初の引数のほうが二番目の引数より大きい場合は正の整数を、二番目の引数と等しい場合はゼロを、そして二番目の引数より小さい場合は負の整数を返す必要があります。
int callback(mixed $a , mixed $b )
警告
float のような 非整数 を比較関数が返すと、その返り値を内部的に int にキャストして使います。
つまり、0.99 や 0.1 といった値は整数値 0 にキャストされ、
値が等しいとみなされます。
例
例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";
}
?>
内部的な比較をさらにシンプルにするために、
宇宙船演算子を使うこともできます。
<?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メソッドです */
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";
}
?>
例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";
}
?>
例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
|