LoginSignup
36

More than 5 years have passed since last update.

【PHP】多次元配列を並び替える方法

Last updated at Posted at 2019-01-23

データベースから取得したデータを並べ替えたいときは、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"
//   }
// }

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36