今回は、PHPでユーザー定義関数でソートをする標準関数の挙動を確認していきます。
前回はsort
・asort
・ksort
などのソート関数について見ていきました。
今回は下記のユーザー定義関数を使用してソートする標準関数を使ってみました。
・uasort
・uksort
ユーザー定義関数でのソートは、配列の内容を関数に定義した処理でソートします。
載せているサンプルコードはPHPのバージョン8で検証しています。
usort・uasort・uksortの比較表
公式ドキュメントからusort・uasort・uksort
の箇所だけ抜き出して、表にしました。
公式ドキュメントはこちらです。
関数 | ソートの基準 | キーと値の相関関係 | ソート順 |
---|---|---|---|
usort | 値 | 維持しない | ユーザー定義 |
uasort | 値 | 維持する | ユーザー定義 |
uksort | キー | 維持する | ユーザー定義 |
ユーザー定義のソート関数はu
から始まっています。
それぞれの違いは、下記になります。
・キーと値の関係を維持するか
また、ソート順のところがユーザー定義になっています。
このユーザー定義は、ユーザーが関数で定義したソート順になります。
詳しくは次項以降で確認してきましょう。
usort関数を使ってソートする
usort
関数は第1引数にソートしたい配列、第2引数にユーザー定義関数を渡してソートします。
ユーザー定義関数は、配列の値を比較する内容で処理を書きます。
下記のように処理を書いて並び替えることができます。
<?php
$fruits = [
1 => 'orange',
2 => 'grape',
3 => 'apple',
4 => 'peach',
5 => 'banana',
];
function mySort($firstValue, $secondValue) {
if ($firstValue === $secondValue) {
return 0;
}
return ($firstValue < $secondValue) ? -1 : 1;
}
usort($fruits, 'mySort');
print_r($fruits);
$fruits
に入っている配列をusort
関数で並び替えています。
並び替えに使っている関数が、第2引数に指定しているmySort
関数です。
mySort
関数の中で、渡された$firstValue
・$secondValue
を比較します。
この2つの変数には、配列の値が入っています。
配列の値を比べて、同じだった場合は0を返しています。
$firstValue
が$secondValue
より小さい場合には-1
を返して、大きい場合には1
を返しています。
これでソートした結果は、下記になります。
Array
(
[0] => apple
[1] => banana
[2] => grape
[3] => orange
[4] => peach
)
このように値を比較する関数を書くことで、配列のデータをソートします。
usort
関数は、「値を基準」にソートして、「キーと値の関係を維持しない」ソートでした。
値がソートされて、キーが振り直されていることが確認できます。
ソート順がユーザー定義ということでした。
下記のように返しているため昇順になっています。
return ($firstValue < $secondValue) ? -1 : 1;
この比較箇所を逆にすると、降順になります。
下記のように比較箇所を反対にします。
return ($firstValue > $secondValue) ? -1 : 1;
そうすると、結果が下記のように、降順になります。
Array
(
[0] => peach
[1] => orange
[2] => grape
[3] => banana
[4] => apple
)
uasort関数を使ってソートする
uasort
関数もusort
関数と同じように使用することが可能です。
こちらも、第1引数にソートしたい配列、第2引数にユーザー定義関数を渡してソートします。
違いは「キーと値の関係を維持する」というところです。
同じ配列を下記のように、uasort
関数でソートしてみました。
<?php
$fruits = [
1 => 'orange',
2 => 'grape',
3 => 'apple',
4 => 'peach',
5 => 'banana',
];
function mySort($firstValue, $secondValue) {
if ($firstValue === $secondValue) {
return 0;
}
return ($firstValue < $secondValue) ? -1 : 1;
}
uasort($fruits, 'mySort');
print_r($fruits);
上記のプログラムの出力結果は下記のようになります。
配列のキーが維持されたまま、下記のように値がソートされていることが確認できました。
Array
(
[3] => apple
[5] => banana
[2] => grape
[1] => orange
[4] => peach
)
こちらも比較箇所を変えることで、降順にできます。
下記のように、比較箇所を変えてみます。
return ($firstValue > $secondValue) ? -1 : 1;
そうすると、結果としてこのように出力されます。
降順になって、キーが維持されていることが確認できました。
Array
(
[4] => peach
[1] => orange
[2] => grape
[5] => banana
[3] => apple
)
uksort関数を使ってソートする
uksort
関数もusort
関数と同じように使用することが可能です。
こちらも、第1引数にソートしたい配列、第2引数にユーザー定義関数を渡してソートします。
usort
関数との違いは「キーを基準にソートする」のと「キーと値の関係を維持する」という箇所です。
同じ配列を下記のように、uksort
関数でソートしてみました。
そのままだと、並び順が変わらないので、配列のキーは変更しました。
<?php
$fruits = [
3 => 'orange',
5 => 'grape',
1 => 'apple',
4 => 'peach',
2 => 'banana',
];
function mySort($firstValue, $secondValue) {
if ($firstValue === $secondValue) {
return 0;
}
return ($firstValue < $secondValue) ? -1 : 1;
}
uksort($fruits, 'mySort');
print_r($fruits);
出力される結果は、下記のようになります。
Array
(
[1] => apple
[2] => banana
[3] => orange
[4] => peach
[5] => grape
)
キーを基準にして、昇順に並ぶことが確認できました。
キーと値の関係も維持されたまま、キーの昇順で並んでいます。
こちらも比較箇所を変えることで、降順にできます。
下記のように変更します。
return ($firstValue > $secondValue) ? -1 : 1;
そうすると、出力結果は下記のようにキーの降順で並ぶようになります。
Array
(
[5] => grape
[4] => peach
[3] => orange
[2] => banana
[1] => apple
)
配列の複数項目でソートする
usort
・uasort
・uksort
のそれぞれの違いの確認ができました。
ユーザー定義のソート関数ということで、複雑なソートを行うことも可能です。
配列の複数の値を元にソートしてみます。
<?php
$items = [
[
'group_id' => 1,
'item_name' => 'apple',
'price' => 120,
],
[
'group_id' => 2,
'item_name' => 'banana',
'price' => 130,
],
[
'group_id' => 1,
'item_name' => 'grape',
'price' => 140,
],
[
'group_id' => 2,
'item_name' => 'orange',
'price' => 150,
],
];
function mySort($firstValue, $secondValue) {
if ($firstValue['group_id'] === $secondValue['group_id']) {
if ($firstValue['price'] === $secondValue['price']) {
return 0;
}
return ($firstValue['price'] > $secondValue['price']) ? -1 : 1;
}
return ($firstValue['group_id'] < $secondValue['group_id']) ? -1 : 1;
}
usort($items, 'mySort');
print_r($items);
$items
を多次元配列にして、それぞれの配列にgroup_id
・item_name
・price
の項目を持っています。
これをusort
関数を使用して、値を基準にソートします。
ソート順は、group_id
の昇順でprice
の降順にします。
mySort
関数の中を確認してもらうと、if文がネストしていますが、このようにすることで複数の項目でソートができます。
最初にgroup_id
を比較して、昇順に並べています。
group_id
が同じだった場合は、price
を参照して、降順にしています。
group_id
からprice
のように、ネストが浅い箇所から、並び順の条件として効いてきます。
このプログラムの出力結果は下記のようになります。
Array
(
[0] => Array
(
[group_id] => 1
[item_name] => grape
[price] => 140
)
[1] => Array
(
[group_id] => 1
[item_name] => apple
[price] => 120
)
[2] => Array
(
[group_id] => 2
[item_name] => orange
[price] => 150
)
[3] => Array
(
[group_id] => 2
[item_name] => banana
[price] => 130
)
)
group_id
が昇順になって、その後にprice
の降順になっているのが確認できます。
終わりに
今回はユーザー定義のソート関数で配列を並べる方法を確認していきました。
usort
・uasort
・uksort
それぞれ同じように使用できますが、結果は異なるので、挙動に注意して使用するようにしましょう。
最後に紹介したように、複数配列の項目の並び順で便利な関数です。
基本的にはデータベースのテーブルから値を取得するときにOrder
句などを使って並べると思います。
データベースを使用できない場合や、配列項目を複数条件で並べたい時に役にたちそうですね。
コメント