単一の配列のソートはPHPマニュアルの配列のソートを参考にすればできますが、多次元配列の場合のソートは複雑…
というわけで、いつでも確認できるように記録しておきます。
多次元配列の例
次のような2次元配列のデータがあるとします。
$records = [
[
'ID' => "A00004",
'PAYMENTNO' => "11111",
'PRICE' => "7500",
'ITEMNAME' => "スニーカー"
],
[
'ID' => "A00002",
'PAYMENTNO' => "22222",
'PRICE' => "4500",
'ITEMNAME' => "カットソー"
],
[
'ID' => "A00001",
'PAYMENTNO' => "05555",
'PRICE' => "5000",
'ITEMNAME' => "ニット"
],
[
'ID' => "A00003",
'PAYMENTNO' => "03333",
'PRICE' => "7000",
'ITEMNAME' => "ジーンズ"
],
[
'ID' => "A00003",
'PAYMENTNO' => "03331",
'PRICE' => "9000",
'ITEMNAME' => "ジャケット"
]
];
この配列に対して、「ID」の昇順で並べ、「ID」の値が同じ場合は「PAYMENTNO」の昇順で並べたいとします。
この場合、array_multisort関数とarray_column関数を組み合わせて使えばスッキリ実装できます。
ソート実行
// array_multisort(ソートの軸となる配列(1), ソートの軸となる配列(2), ソートしたい配列)
array_multisort(array_column($records, 'ID'), array_column($records, 'PAYMENTNO'), $records);
ここではソートの軸を2つにしていますが、もちろん1つでも良いですし、引数を追加すれば3つでも4つでも増やせます。
省略せずに書くなら
array_multisort(ソートの軸となる配列(1), ソート順(1), ソート方法(1), ソートの軸となる配列(2), ソート順(2), ソート方法(2), ソートしたい配列)
となりますが、以下2つはデフォルトの設定を使うのであれば省略可能です。
- ソート順:デフォルトがSORT_ASC
- ソート方法:デフォルトがSORT_REGULAR
※設定の詳細は公式リファレンス参照
この「ソートの軸となる配列」は、$recordsをforeachで回してIDを取り出して、配列を作成して…としても良いのですが、array_columnを使えば配列から特定のキーに対する要素を1発で取り出せるので、この方が楽でコードもスッキリします。
array_column関数
ソート後
上でソートした配列$records
をvar_dumpしてみると、以下のようになります。
array(5) {
[0]=>
array(4) {
["ID"]=>
string(6) "A00001"
["PAYMENTNO"]=>
string(5) "05555"
["PRICE"]=>
string(4) "5000"
["ITEMNAME"]=>
string(9) "ニット"
}
[1]=>
array(4) {
["ID"]=>
string(6) "A00002"
["PAYMENTNO"]=>
string(5) "22222"
["PRICE"]=>
string(4) "4500"
["ITEMNAME"]=>
string(15) "カットソー"
}
[2]=>
array(4) {
["ID"]=>
string(6) "A00003"
["PAYMENTNO"]=>
string(5) "03331"
["PRICE"]=>
string(4) "9000"
["ITEMNAME"]=>
string(15) "ジャケット"
}
[3]=>
array(4) {
["ID"]=>
string(6) "A00003"
["PAYMENTNO"]=>
string(5) "03333"
["PRICE"]=>
string(4) "7000"
["ITEMNAME"]=>
string(12) "ジーンズ"
}
[4]=>
array(4) {
["ID"]=>
string(6) "A00004"
["PAYMENTNO"]=>
string(5) "11111"
["PRICE"]=>
string(4) "7500"
["ITEMNAME"]=>
string(15) "スニーカー"
}
}
ちゃんと「ID」の昇順かつ、「ID」が同じ場合は「PAYMENTNO」の昇順になっていますね!