複数または多次元の配列をソートする

# array_multisort

(PHP 4, PHP 5, PHP 7, PHP 8)

array_multisort — 複数または多次元の配列をソートする

### 説明

function array_multisort(
array `&$array1`,
mixed `$array1_sort_order` = SORT_ASC,
mixed `$array1_sort_flags` = SORT_REGULAR,
mixed `...$rest`
): true

array_multisort() は、複数の配列を一度に、 または、多次元の配列をその次元の一つでソートする際に使用可能です。

連想配列のキー (string) は不変ですが、 数値添字は再度振り直されます。

> 注意: 比較結果が等しくなる二つの要素があった場合、それらの並び順は保持されます。PHP 8.0.0 より前のバージョンでは、ソートした配列におけるそれらの並び順は不定でした。

> 注意: この関数をコールすると、配列の内部ポインタは最初の要素にリセットされます。

### パラメータ

`array1`

  ソートしたい配列。

`array1_sort_order`

  先ほどの引数 array のソート順。 `SORT_ASC` はアイテムを昇順にソートし、 `SORT_DESC` はアイテムを降順にソートします。

  この引数は、`array1_sort_flags` と入れ替えることもできるし、完全に省略することもできます。 省略した場合は `SORT_ASC` とみなします。

`array1_sort_flags`

  先ほどの引数 array のソート方法。

  これらのフラグが使えます。

  - `SORT_REGULAR` - アイテムを通常通り比較します (型を変更しません)。
  - `SORT_NUMERIC` - アイテムを数値として比較します。
  - `SORT_STRING` - アイテムを文字列として比較します。
  - `SORT_LOCALE_STRING` - 現在のロケールを考慮して、アイテムを文字列として比較します。利用するロケールは setlocale() で変更できます。
  - `SORT_NATURAL` - natsort() と同様の「自然順」で、アイテムを文字列として比較します。
  - `SORT_FLAG_CASE` - `SORT_STRING` や `SORT_NATURAL` と (ビット OR で) 組み合わせて、 大文字小文字を区別しない文字列のソートを指定します。

  この引数は、`array1_sort_order` と入れ替えることもできるし、完全に省略することもできます。 省略した場合は `SORT_REGULAR` とみなします。

`rest`

  追加の配列。オプションで並び順やフラグが続きます。 前の配列の比較結果が等しい要素に対応する要素群だけを比較します。 要するに、辞書的 (lexicographical) なソートを行うということです。

### 戻り値

常に `true` を返します。

### 変更履歴

バージョン | 説明
--- | ---
8.5.0 | 戻り値の型が、`true` になりました。これより前のバージョンでは、bool でした。

### 例

例1 複数の配列をソートする

    <?php
    $ar1 = array(10, 100, 100, 0);
    $ar2 = array(1, 3, 2, 4);
    array_multisort($ar1, $ar2);

    var_dump($ar1);
    var_dump($ar2);
    ?>

この例では、ソートの後で、最初の配列は、0, 10, 100, 100 となります。 2番目の配列は、4, 1, 2, 3 を有します。最初の配列で等しい要素 (100 および 100) に対応している二番目の配列のエントリは、 同じ順にソートされます。

    array(4) {
      [0]=> int(0)
      [1]=> int(10)
      [2]=> int(100)
      [3]=> int(100)
    }
    array(4) {
      [0]=> int(4)
      [1]=> int(1)
      [2]=> int(2)
      [3]=> int(3)
    }

例2 多次元の配列をソートする

    <?php
    $ar = array(
           array("10", 11, 100, 100, "a"),
           array(   1,  2, "2",   3,   1)
          );
    array_multisort($ar[0], SORT_ASC, SORT_STRING,
                    $ar[1], SORT_NUMERIC, SORT_DESC);
    var_dump($ar);
    ?>

この例では、ソートされた後、最初の配列は "10", 100, 100, 11, "a" (文字列として昇順でソートされています) に変換され、二番目の配列は、 1, 3, "2", 2, 1 (数値として降順にソートされています) となっています。

    array(2) {
      [0]=> array(5) {
        [0]=> string(2) "10"
        [1]=> int(100)
        [2]=> int(100)
        [3]=> int(11)
        [4]=> string(1) "a"
      }
      [1]=> array(5) {
        [0]=> int(1)
        [1]=> int(3)
        [2]=> string(1) "2"
        [3]=> int(2)
        [4]=> int(1)
      }
    }

例3 データベースの結果をソートする

この例では、配列 data の個々の要素がテーブルのひとつの行を表しています。 これは、データベースのレコードの典型的な形式です。

データの例:

    volume | edition
    -------+--------
        67 |       2
        86 |       1
        85 |       6
        98 |       2
        86 |       6
        67 |       7

データは data という名前の配列に格納します。 これは、例えば mysql_fetch_assoc() の結果をループさせたりすれば得られます。

この例では、データを volume の降順、 edition の昇順に並べ替えます。

私たちが今もっているのは行方向の配列ですが、 array_multisort() で必要なのは列方向の配列です。 そこで、以下のコードで列方向の配列を得たあとでソートを行います。

    <?php
    // このデータは、mysqli_fetch_assoc の結果をループして作られます:
    $data[] = array('volume' => 67, 'edition' => 2);
    $data[] = array('volume' => 86, 'edition' => 1);
    $data[] = array('volume' => 85, 'edition' => 6);
    $data[] = array('volume' => 98, 'edition' => 2);
    $data[] = array('volume' => 86, 'edition' => 6);
    $data[] = array('volume' => 67, 'edition' => 7);

    // カラムのリストを取得
    foreach ($data as $key => $row) {
        $volume[$key]  = $row['volume'];
        $edition[$key] = $row['edition'];
    }

    // 上記のコードの代わりに array_column() を使用できます
    $volume  = array_column($data, 'volume');
    $edition = array_column($data, 'edition');

    // データを volume の降順でソートし、edition の昇順でソート
    // $data を最後のパラメータとして追加
    array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data);

    // $data をループし、ソート済みの値をカラムごとに出力
    echo 'volume | edition', PHP_EOL;
    echo '-------+--------', PHP_EOL;
    for ($i = 0; $i < count($data); $i++) {
         printf("%6d | %7d\n", $volume[$i], $edition[$i]);
    }
    ?>

データセットの行はソートされ、以下のようになります:

    volume | edition
    -------+--------
        98 |       2
        86 |       1
        86 |       6
        85 |       6
        67 |       2
        67 |       7

例4 大文字・小文字を区別しないソート

`SORT_STRING` と `SORT_REGULAR` はどちらも大文字・小文字を区別し、 大文字ではじまる文字列が小文字で始まる文字列より前になります。

大文字・小文字を区別しないためには、 元の配列の内容をすべて小文字に変換した配列を用意し、 それをソートの基準にします。

    <?php
    $array = array('Alpha', 'atomic', 'Beta', 'bank');
    $array_lowercase = array_map('strtolower', $array);

    array_multisort($array_lowercase, SORT_ASC, SORT_STRING, $array);

    print_r($array);
    ?>

上の例の出力は以下となります。

    Array
    (
        [0] => Alpha
        [1] => atomic
        [2] => bank
        [3] => Beta
    )

### 参考

- usort() - ユーザー定義の比較関数を使用して、配列を値でソートする
- 配列ソート関数の比較

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open