データベースから取得したデータを並べ替えたいときは、SQL中でORDER BY
が使われます。
SQLやORマッパーで処理が完結すれば良いのですが、取得したデータに対して何らかの操作をし、その操作結果を元に、配列として並べ替えたい場合もあるかもしれません。(しかも多次元配列・・・)
なので、多次元配列を並べ替える方法をいくつか書き留めておきます。
テスト用配列
$clothes = array(
array(
'type' => 'male',
'size' => 'S',
'release_date' => '2019-04-10'
),
array(
'type' => 'female',
'size' => 'M',
'release_date' => '2019-02-15'
),
array(
'type' => 'child',
'size' => 'S',
'release_date' => '2019-01-05'
),
array(
'type' => 'female',
'size' => 'M',
'release_date' => '2019-05-20'
),
array(
'type' => 'male',
'size' => 'L',
'release_date' => '2019-03-30'
)
);
var_dump($clothes);
// 出力結果
// array(5) {
// [0]=>
// array(3) {
// ["type"]=>
// string(4) "male"
// ["size"]=>
// string(1) "S"
// ["release_date"]=>
// string(10) "2019-04-10"
// }
// [1]=>
// array(3) {
// ["type"]=>
// string(6) "female"
// ["size"]=>
// string(1) "M"
// ["release_date"]=>
// string(10) "2019-02-15"
// }
// [2]=>
// array(3) {
// ["type"]=>
// string(5) "child"
// ["size"]=>
// string(1) "S"
// ["release_date"]=>
// string(10) "2019-01-05"
// }
// [3]=>
// array(3) {
// ["type"]=>
// string(6) "female"
// ["size"]=>
// string(1) "M"
// ["release_date"]=>
// string(10) "2019-05-20"
// }
// [4]=>
// array(3) {
// ["type"]=>
// string(4) "male"
// ["size"]=>
// string(1) "L"
// ["release_date"]=>
// string(10) "2019-03-30"
// }
// }
1つのキー(カラム)を基準にソートする
多次元配列の並べ替えには、array_multisort
を使います。
基準となるキーを指定し、そのキーに対応する値を格納する配列を作成します。
それを元にソートが行われます。
<?php
// 指定したキーに対応する値を基準に、配列をソートする
function sortByKey($key_name, $sort_order, $array) {
foreach ($array as $key => $value) {
$standard_key_array[$key] = $value[$key_name];
}
array_multisort($standard_key_array, $sort_order, $array);
return $array;
}
// release_dateを昇順ソートする
$sorted_array = sortByKey('release_date', SORT_ASC, $clothes);
var_dump($sorted_array);
// 出力結果
// array(5) {
// [0]=>
// array(3) {
// ["type"]=>
// string(5) "child"
// ["size"]=>
// string(1) "S"
// ["release_date"]=>
// string(10) "2019-01-05"
// }
// [1]=>
// array(3) {
// ["type"]=>
// string(6) "female"
// ["size"]=>
// string(1) "M"
// ["release_date"]=>
// string(10) "2019-02-15"
// }
// [2]=>
// array(3) {
// ["type"]=>
// string(4) "male"
// ["size"]=>
// string(1) "L"
// ["release_date"]=>
// string(10) "2019-03-30"
// }
// [3]=>
// array(3) {
// ["type"]=>
// string(4) "male"
// ["size"]=>
// string(1) "S"
// ["release_date"]=>
// string(10) "2019-04-10"
// }
// [4]=>
// array(3) {
// ["type"]=>
// string(6) "female"
// ["size"]=>
// string(1) "M"
// ["release_date"]=>
// string(10) "2019-05-20"
// }
// }
複数のキー(カラム)を基準にソートする
array_multisort
を使用する点、基準となるキーを指定し、そのキーに対応する値を格納する配列を作成する点は同じです。
SQLではORDER BY type ASC, size ASC, release_date ASC
に当たる書き方です。
array_multisort
の引数に、ソートの優先順に基準となる配列と並び順を指定します。
<?php
// ソートの基準となるキーに対応する値の配列を作成
function createArrayForSort($key_name, $array) {
foreach ($array as $key => $value) {
$standard_key_array[$key] = $value[$key_name];
}
return $standard_key_array;
}
// 各キーを基準にソートできるように、対応する値の配列を作成
$type_array = createArrayForSort('type', $clothes);
$size_array = createArrayForSort('size', $clothes);
$release_date_array = createArrayForSort('release_date', $clothes);
// type, size, release_dateの優先順位で昇順ソートする
array_multisort($type_array, SORT_ASC, $size_array, SORT_ASC, $release_date_array, SORT_ASC, $clothes);
var_dump($clothes);
// 出力結果
// array(5) {
// [0]=>
// array(3) {
// ["type"]=>
// string(5) "child"
// ["size"]=>
// string(1) "S"
// ["release_date"]=>
// string(10) "2019-01-05"
// }
// [1]=>
// array(3) {
// ["type"]=>
// string(6) "female"
// ["size"]=>
// string(1) "M"
// ["release_date"]=>
// string(10) "2019-02-15"
// }
// [2]=>
// array(3) {
// ["type"]=>
// string(6) "female"
// ["size"]=>
// string(1) "M"
// ["release_date"]=>
// string(10) "2019-05-20"
// }
// [3]=>
// array(3) {
// ["type"]=>
// string(4) "male"
// ["size"]=>
// string(1) "L"
// ["release_date"]=>
// string(10) "2019-03-30"
// }
// [4]=>
// array(3) {
// ["type"]=>
// string(4) "male"
// ["size"]=>
// string(1) "S"
// ["release_date"]=>
// string(10) "2019-04-10"
// }
// }
ユーザー基準でソートする
array_multisort
のソートのバリエーションは限られています。
配列をユーザー基準で並び替えたい場合、以下の方法が使えるかと思います。
あらかじめ、ソートの基準にするキーに対応する値をキーとした多次元配列を作成します。そこに配列の各要素を振り分けます。
ソート用のユーザー定義関数を作成するなど、他の方法もあるかもしれません。
<?php
// あらかじめ表示順の基準とするキーに対応する値をキーとした配列を作成する
$array_by_size = array(
'S' => array(),
'M' => array(),
'L' => array()
);
// 値に応じて各要素を振り分ける
foreach($clothes as $key => $value) {
$array_by_size[$value['size']][] = $value;
}
// 多次元配列で扱いづらいため、次元を1つ減らす
$sorted_array = call_user_func_array('array_merge', $array_by_size);
// array_mergeも使用できる
// $merge_array = array();
// foreach($array_by_size as $key => $value) {
// foreach ($value as $data) {
// $sorted_array[] = array_merge($merge_array, $data);
// }
// }
var_dump($sorted_array);
// 出力結果
// array(5) {
// [0]=>
// array(3) {
// ["type"]=>
// string(4) "male"
// ["size"]=>
// string(1) "S"
// ["release_date"]=>
// string(10) "2019-04-10"
// }
// [1]=>
// array(3) {
// ["type"]=>
// string(5) "child"
// ["size"]=>
// string(1) "S"
// ["release_date"]=>
// string(10) "2019-01-05"
// }
// [2]=>
// array(3) {
// ["type"]=>
// string(6) "female"
// ["size"]=>
// string(1) "M"
// ["release_date"]=>
// string(10) "2019-02-15"
// }
// [3]=>
// array(3) {
// ["type"]=>
// string(6) "female"
// ["size"]=>
// string(1) "M"
// ["release_date"]=>
// string(10) "2019-05-20"
// }
// [4]=>
// array(3) {
// ["type"]=>
// string(4) "male"
// ["size"]=>
// string(1) "L"
// ["release_date"]=>
// string(10) "2019-03-30"
// }
// }