PHPプログラミング

ベストプラクティス

配列

多次元配列のソート:array_multisort関数

  • このエントリーをはてなブックマークに追加

データベースから取得したデータなど、多次元の配列を特定のデータを軸にして並び替えたいことがあります。今回はそんな時に重宝するarray_multisort関数の使い方を解説します。

目次

  1. #  ものすごく便利な多次元配列の並び替え
  2. #  array_multisort関数について
  3. #  改めてコードを解説

ものすごく便利な多次元配列の並び替え

単一の配列であればソートは簡単ですが、2次元以上の配列をソートしたいときは軸にしたい値がピンポイントであったり、複数ある場合があります。
例えば、データベースから次のような多次元配列のデータを取得したとします。

array (size=5)
  0 => 
    array (size=5)
      'id' => int 1
      'name' => string '山本太郎' (length=12)
      'age' => int 12
      'rank' => int 2
      'regist_datetime' => string '2017-02-01 10:00' (length=16)
  1 => 
    array (size=5)
      'id' => int 3
      'name' => string '佐藤孝宏' (length=12)
      'age' => int 32
      'rank' => int 2
      'regist_datetime' => string '2017-02-15 10:00' (length=16)
  2 => 
    array (size=5)
      'id' => int 5
      'name' => string '飯田智子' (length=12)
      'age' => int 22
      'rank' => int 1
      'regist_datetime' => string '2017-02-20 12:00' (length=16)
  3 => 
    array (size=5)
      'id' => int 6
      'name' => string '岡田嘉子' (length=12)
      'age' => int 35
      'rank' => int 1
      'regist_datetime' => string '2017-02-01 08:00' (length=16)
  4 => 
    array (size=5)
      'id' => int 7
      'name' => string '渡辺智' (length=9)
      'age' => int 25
      'rank' => int 2
      'regist_datetime' => string '2017-03-17 10:00' (length=16)

この配列に対して「rank」を昇順に並べて、さらに同じランクの中では「id」を昇順に並べたいとします。
その場合は、次のコードで意図した通りのソートを行うことができます。

// $dataに上記の配列が入っている
$id_array = array();
$rank_array = array();

foreach( $data as $value ) {
	$id_array[] = $value['id'];
	$rank_array[] = $value['rank'];
}

// ソートを実行
array_multisort( $rank_array, SORT_ASC, $id_array, SORT_ASC, $data);

実行結果

実行すると、次のように並び替えられます。

array (size=5)
  0 => 
    array (size=5)
      'id' => int 5
      'name' => string '飯田智子' (length=12)
      'age' => int 22
      'rank' => int 1
      'regist_datetime' => string '2017-02-20 12:00' (length=16)
  1 => 
    array (size=5)
      'id' => int 6
      'name' => string '岡田嘉子' (length=12)
      'age' => int 35
      'rank' => int 1
      'regist_datetime' => string '2017-02-01 08:00' (length=16)
  2 => 
    array (size=5)
      'id' => int 1
      'name' => string '山本太郎' (length=12)
      'age' => int 12
      'rank' => int 2
      'regist_datetime' => string '2017-02-01 10:00' (length=16)
  3 => 
    array (size=5)
      'id' => int 3
      'name' => string '佐藤孝宏' (length=12)
      'age' => int 32
      'rank' => int 2
      'regist_datetime' => string '2017-02-15 10:00' (length=16)
  4 => 
    array (size=5)
      'id' => int 7
      'name' => string '渡辺智' (length=9)
      'age' => int 25
      'rank' => int 2
      'regist_datetime' => string '2017-03-17 10:00' (length=16)

解説

実際にソートを実行しているのはarray_multisort関数です。
引数で渡しているものが多く、ちょっと分かりづらいかもしれません。
そこで、まずは関数の基本的な使い方からみていきましょう。

array_multisort関数について

array_multisort関数は次のような引数を取ります。

array_multisort( ソートの軸となる配列, 並び順, ソート方法, ソートしたい配列);

「ソートの軸となる配列」は、ソートしたい値だけが入った配列です。
先ほどのコードにあった$rank_arrayは「rank」の値だけが入った配列になります。

次の「並び順」はソートを昇順・降順のどちらで行うかを指定します。
昇順の場合は「SORT_ASC」、降順の場合は「SORT_DESC」です。
この指定は省略することが可能で、もし指定しない場合は初期値の「昇順(SORT_ASC)」になります。

続く「ソート方法」は、ソートをする時の比較方法の指定です。
この関数では、次の5つを指定することができます。

  • SORT_REGULAR – 型の変換をせず、通常通りの比較。
  • SORT_NUMERIC 数値として比較。
  • SORT_STRING – 文字列として比較。
  • SORT_LOCALE_STRING – 使用している言語を踏まえたうえで、文字列として比較。言語はsetlocale関数で指定します。
  • SORT_NATURAL – 「自然順」で、文字列として比較。

上記に加え、大文字小文字を区別せずに文字列として比較するための「SORT_FLAG_CASE」があります。
こちらは「SORT_STRING」や「SORT_NATURAL」とセットで指定します。

ソート方法も省略可能となり、省略した場合は初期値のSORT_REGULARになります。

最後の引数にはソートをしたい配列を渡します。

ここでポイントとなるのは、「ソートの軸となる配列 & 並び順 & ソート方法」の組み合わせは複数指定することが可能ということです。
2つでも3つでも指定することができてしまいます。
これが痒い所に手が届いてすごく便利!

例えば、ソートしたい多次元配列$dataがあったとして、3つの組み合わせでソートを実行する時は次のコードになります。
※コードを簡略化するために「ソート方法」の指定は省略。

array_multisort( $key_array1, SORT_ASC, $key_array2, SORT_ASC, $key_array3, SORT_DESC, $data);

こちらの関数を実行すると、ソート後の配列が自動的に$dataへ格納されます。

改めてコードを解説

基本的な使い方が分かったところで、改めて最初のコードを確認します。

array_multisort( $rank_array, SORT_ASC, $id_array, SORT_ASC, $data);

関数の使い方を確認したのでもうお分かりかもしれませんが、5つある引数のうち、$rank_array$id_arrayソートのキーとなる配列$dataソートを行いたい配列です。

分かりやすいように明示的に「SORT_ASC」を指定していますが、実際には次のように書いても結果は同じになります。

array_multisort( $rank_array, $id_array, $data);

ソートを実行する前にforeach文を使い、配列内の全要素からIDとランクのデータを$id_array$rank_arrayへそれぞれ格納しています。
こちらは前準備にあたりますね。

多次元配列のソートではソートの軸となる値が2つ、3つと掛け合わせになることは頻繁にあるため、array_multisort関数は非常に便利で重宝します。

以上、多次元配列のソートについてでした。

  • このエントリーをはてなブックマークに追加