最終更新日:
公開日:
レシピ
配列
多次元配列のソート:array_multisort関数
array_multisort関数を使って、多次元配列を特定のキーを軸にして並び替える方法について解説します。
この記事のポイント
- 多次元配列を特定の値を軸にしてソートする
- ソートの軸になる値を2つ以上指定する
目次
ものすごく便利な多次元配列のソート
単一の配列のソートは簡単ですが、2次元以上の多次元になっている配列をソートしたいときはソートの基準となるキーや値が複数になるため複雑になります。
例えば、次のような2次元配列のデータがあるとします。
多次元配列の例
$array = array(
array(
'id' =>1,
'name' =>'柴犬',
'age' =>8,
'regist_datetime' =>'2017-02-01 10:00'
),
array(
'id' =>2,
'name' =>'ポメラニアン',
'age' =>3,
'regist_datetime' =>'2017-02-15 10:00'
),
array(
'id' =>5,
'name' =>'ゴールデンレトリバー',
'age' =>8,
'regist_datetime' =>'2017-02-16 15:00'
),
array(
'id' =>6,
'name' =>'グレイハウンド',
'age' =>6,
'regist_datetime' =>'2017-02-16 16:30'
),
array(
'id' =>8,
'name' =>'シベリアンハスキー',
'age' =>3,
'regist_datetime' =>'2017-02-16 19:00'
)
);
この配列に対して、年齢を表す「age」の値を基準に昇順に並べ、さらに値が同じ場合は「id」を降順に並べたいとします。
このように多次元配列で複数の値を軸にしてソートしたい場合、単一の配列よりもやや複雑ですがarray_multisort関数を使うことで意図したソートを実現できます。
PHP コード例
<?php
// 配列の初期化
$array = array();
$id_array = array();
$age_array = array();
// 多次元配列を作成
$array = array(
array(
'id' => 1,
'name' => '柴犬',
'age' => 8,
'regist_datetime' => '2017-02-01 10:00'
),
array(
'id' => 2,
'name' => 'ポメラニアン',
'age' => 3,
'regist_datetime' => '2017-02-15 10:00'
),
array(
'id' => 5,
'name' => 'ゴールデンレトリバー',
'age' => 8,
'regist_datetime' => '2017-02-16 15:00'
),
array(
'id' => 6,
'name' => 'グレイハウンド',
'age' => 6,
'regist_datetime' => '2017-02-16 16:30'
),
array(
'id' => 8,
'name' => 'シベリアンハスキー',
'age' => 3,
'regist_datetime' => '2017-02-16 19:00'
)
);
// ソートの基準となる「id」と「age」を配列に入れる
foreach( $array as $value) {
$id_array[] = $value['id'];
$age_array[] = $value['age'];
}
// ソート前の配列を出力
var_dump($array);
// ソート実行
array_multisort( $age_array, SORT_ASC, SORT_NUMERIC, $id_array, SORT_DESC, SORT_NUMERIC, $array);
// ソート後の配列を出力
var_dump($array);
配列のソート実行前、実行後はそれぞれ次のようになります。
ソート前の出力例
array(5) {
[0]=> array(4) {
["id"]=> int(1)
["name"]=> string(6) "柴犬"
["age"]=> int(8)
["regist_datetime"]=> string(16) "2017-02-01 10:00"
}
[1]=> array(4) {
["id"]=> int(2)
["name"]=> string(18) "ポメラニアン"
["age"]=> int(3)
["regist_datetime"]=> string(16) "2017-02-15 10:00"
}
[2]=> array(4) {
["id"]=> int(5)
["name"]=> string(30) "ゴールデンレトリバー"
["age"]=> int(8)
["regist_datetime"]=> string(16) "2017-02-16 15:00"
}
[3]=> array(4) {
["id"]=> int(6)
["name"]=> string(21) "グレイハウンド"
["age"]=> int(6)
["regist_datetime"]=> string(16) "2017-02-16 16:30"
}
[4]=> array(4) {
["id"]=> int(8)
["name"]=> string(27) "シベリアンハスキー"
["age"]=> int(3)
["regist_datetime"]=> string(16) "2017-02-16 19:00"
}
}
ソート後の出力例
array(5) {
[0]=> array(4) {
["id"]=> int(8)
["name"]=> string(27) "シベリアンハスキー"
["age"]=> int(3)
["regist_datetime"]=> string(16) "2017-02-16 19:00"
}
[1]=> array(4) {
["id"]=> int(2)
["name"]=> string(18) "ポメラニアン"
["age"]=> int(3)
["regist_datetime"]=> string(16) "2017-02-15 10:00"
}
[2]=> array(4) {
["id"]=> int(6)
["name"]=> string(21) "グレイハウンド"
["age"]=> int(6)
["regist_datetime"]=> string(16) "2017-02-16 16:30"
}
[3]=> array(4) {
["id"]=> int(5)
["name"]=> string(30) "ゴールデンレトリバー"
["age"]=> int(8)
["regist_datetime"]=> string(16) "2017-02-16 15:00"
}
[4]=> array(4) {
["id"]=> int(1)
["name"]=> string(6) "柴犬"
["age"]=> int(8)
["regist_datetime"]=> string(16) "2017-02-01 10:00"
}
}
意図した通り、年齢の昇順、idの降順で配列がソートされました。
array_multisort関数は、次のようにパラメータを受け取ってソートを行います。
array_multisort関数の使い方
array_multisort( ソートの軸となる配列(1), 並び順(1), ソートするデータの型(1), ソートの軸となる配列(2), 並び順(2), ソートするデータの型(2), ソートしたい配列);
上記のように、ソートの基準データの指定はデータの入った配列、並び順の指定、データの型の3つを1セットに指定します。
この中で、「並び順」と「データの型」はオプションとなるため省略できます。
この関数は実行すると、ソートした後の配列が自動的に「ソートしたい配列」で指定した配列に格納されます。
返り値はソートに成功したら「true」、失敗した場合は「false」です。
今回のコード例ではソートの軸になるデータを「年齢」と「id」の2つ設定していますが、1つでも3つでも、もしくはそれ以上を指定することも可能です。
ソートの軸となる配列が1つの場合
array_multisort( ソートの軸となる配列, 並び順, ソートするデータの型, ソートしたい配列);
ソートの軸となる配列が3つの場合
array_multisort( ソートの軸となる配列(1), 並び順(1), ソートするデータの型(1), ソートの軸となる配列(2), 並び順(2), ソートするデータの型(2), ソートの軸となる配列(3), 並び順(3), ソートするデータの型(3), ソートしたい配列);
今回の配列でソートする軸の配列を3つにした場合は、次のようになります。
ソートの軸とが3つのコード例
array_multisort( $age_array, SORT_ASC, SORT_NUMERIC, $id_array, SORT_DESC, SORT_NUMERIC, $name_array, SORT_ASC, SORT_STRING, $array);
ソートの軸となる配列はソート実行前に用意します。
この配列はソートする値のみが入っている状態にする必要があります。
上記コードではforeach文で$arrayのデータを1つずつ取り出して、$age_arrayと$id_arrayにそれぞれの値を格納して作成しています。
PHP コード例
// ソートの基準となる「id」と「age」を配列に入れる
foreach( $array as $value) {
$id_array[] = $value['id'];
$age_array[] = $value['age'];
}
あとはこの配列をarray_multisort関数に渡して実行するだけでOKです。
データの型について
つい忘れがちですが、軸となるデータの型はしっかり指定しておいた方が確実にソートすることができます。
指定できる型は次の6種類です。
定数 | 説明 |
---|---|
SORT_REGULAR | 型の変換をせずに比較 |
SORT_NUMERIC | 数値として比較 |
SORT_STRING | 文字列として比較 |
SORT_LOCALE_STRING | 使用している言語を踏まえたうえで、文字列として比較。言語はsetlocale関数で指定します。 |
SORT_NATURAL | 「自然順」で、文字列として比較 |
SORT_FLAG_CASE | アルファベットの大文字、小文字を区別しないでソートの比較。SORT_STRINGなどと論理和で指定して実行 |
最後の「SORT_FLAG_CASE」だけやや分かりづらいですが、論理和を使った指定は次のように「| (パイプライン)」を使って行います。
PHP コード例
array_multisort( $name_array, SORT_DESC, SORT_STRING | SORT_FLAG_CASE, $array);