1. ホーム
  2. php

[解決済み】PHPで配列やデータをソートするにはどうすればいいですか?

2022-03-27 22:41:40

質問

<ブロッククオート

この質問は、PHPでの配列のソートに関する質問の参考とするためのものです。あなたの特定のケースがユニークで、新しい質問をする価値があると思うのは簡単ですが、実際にはほとんどの場合、このページにある解決策のうちの1つの小さなバリエーションです。

もし、あなたの質問がこの質問と重複しているとして閉じられてしまった場合は、以下のすべての質問と著しく異なる理由を説明できる場合に限り、あなたの質問を再開するよう申し出てください。

PHPで配列を並べ替えるにはどうしたらいいですか?

をソートするにはどうすればよいのでしょうか? 複雑 の配列は、PHP で使用できますか?

PHPでオブジェクトの配列を並べ替えるには?


  1. 基本的な一次元配列; 多次元配列(オブジェクトの配列を含む); ある配列を別の配列で並べ替えるを含む

  2. SPLによるソート

  3. 安定したソート

PHP の既存の関数を使用した実用的な回答は 1.を、ソートアルゴリズムに関する学術的な詳細な回答は (PHP の関数が実装していて、あなたが かもしれない は、本当に複雑な場合に必要です。

解決方法は?

1次元配列の基本

$array = array(3, 5, 2, 8);

適用可能なソート機能

  • sort
  • rsort
  • asort
  • arsort
  • natsort
  • natcasesort
  • ksort
  • krsort

これらの違いは、単にキーと値の関連付けが保たれているかどうかということです(" a 関数)、下位から上位へのソートか逆方向のソートか(" r ")、値またはキーのどちらをソートするか(" k ")、値の比較方法(" nat vs. 通常)。参照 http://php.net/manual/en/array.sorting.php をご覧ください。

オブジェクトの配列を含む、多次元の配列

$array = array(
    array('foo' => 'bar', 'baz' => 42),
    array('foo' => ...,   'baz' => ...),
    ...
);

並べ替えを行う場合 $array を各エントリのキー 'foo' で置き換えるには カスタム比較関数 . 上記の sort と関連する関数は、比較や並べ替えの方法を知っている単純な値に対して動作します。PHPは、単に 複雑な値 のように array('foo' => 'bar', 'baz' => 42) ということを伝える必要があります。

そのためには 比較関数 . この関数は、2つの要素を受け取り、そのうちの1つを返さなければなりません。 0 これらの要素が等しいと見なされる場合、以下の値を返します。 0 よりも小さい場合、また、最初の値が 0 は、最初の値が大きければ これだけでいいのです。

function cmp(array $a, array $b) {
    if ($a['foo'] < $b['foo']) {
        return -1;
    } else if ($a['foo'] > $b['foo']) {
        return 1;
    } else {
        return 0;
    }
}

多くの場合、このような場合は 匿名機能 をコールバックとして使用します。メソッドや静的メソッドを使用したい場合は PHP でコールバックを指定する他の方法 .

そして、これらの関数のいずれかを使用します。

ここでも、キーと値の関連付けを維持するか、値でソートするかキーでソートするかの違いしかない。詳しくはそれぞれのドキュメントをご覧ください。

使用例です。

usort($array, 'cmp');

usort は、配列から 2 つの項目を取り出して cmp 関数に渡すことができます。つまり cmp() が呼び出されます。 $a として array('foo' => 'bar', 'baz' => 42)$b を別の array('foo' => ..., 'baz' => ...) . この関数は、次に usort のどちらが大きいか、あるいは等しいか。 usort に異なる値を渡してこの処理を繰り返す。 $a$b 配列がソートされるまで このとき cmp 関数が何度も呼び出されます。 少なくとも にある値の数だけ $array の値の組み合わせが異なる。 $a$b を毎回使用します。

この考え方に慣れるために、こうしてみてください。

function cmp($a, $b) {
    echo 'cmp called with $a:', PHP_EOL;
    var_dump($a);
    echo 'and $b:', PHP_EOL;
    var_dump($b);
}

あなたがしたことは、2つの項目を比較するカスタム方法を定義したこと、それだけです。あらゆる種類の値で機能します。

ちなみに、これはどんな値に対しても有効で、値が複雑な配列である必要はない。もしカスタムで比較したいものがあれば、単純な数値の配列に対しても行うことができます。

sort は参照でソートし、何も有用なものを返しません

なお、配列のソートは その場で の場合、戻り値を何かに代入する必要はありません。 $array = sort($array) で配列を置き換えます。 true であり、ソートされた配列ではありません。ただ sort($array); が動作します。

数値比較のカスタマイズ

で並べ替えたい場合は baz というキーがあり、これは数字なので、必要なことはそれだけです。

function cmp(array $a, array $b) {
    return $a['baz'] - $b['baz'];
}

ありがとうございます 数学のポワレ(The PoWEr oF MATH のいずれかに応じて、0、0、または 0 を返します。 $a よりも小さいか、等しいか、大きいかです。 $b .

の場合、うまくいかないことに注意してください。 float という値になってしまうからです。 int となり、精度が落ちます。明示的な -1 , 01 は代わりに値を返します。

オブジェクト

オブジェクトの配列がある場合も、同じように動作します。

function cmp($a, $b) {
    return $a->baz - $b->baz;
}

機能紹介

比較関数の内部では、関数の呼び出しを含め、必要なことは何でもできます。

function cmp(array $a, array $b) {
    return someFunction($a['baz']) - someFunction($b['baz']);
}

文字列

最初の文字列比較版のショートカットです。

function cmp(array $a, array $b) {
    return strcmp($a['foo'], $b['foo']);
}

strcmp は、まさに cmp を返します。 -1 , 0 または 1 .

宇宙船オペレーター

PHP 7 では スペースシップ演算子 これは、型によらず等しい/小さい/大きいの比較を統一し、簡素化するものです。

function cmp(array $a, array $b) {
    return $a['foo'] <=> $b['foo'];
}

複数フィールドによるソート

主に以下の条件で並べ替えたい場合 foo が、もし foo でソートされた2つの要素で等しい場合は baz :

function cmp(array $a, array $b) {
    if (($cmp = strcmp($a['foo'], $b['foo'])) !== 0) {
        return $cmp;
    } else {
        return $a['baz'] - $b['baz'];
    }
}

これは、SQLクエリに相当します。 ORDER BY foo, baz .

こちらもご覧ください このとてもすてきな略記版 このような比較関数を任意の数のキーに対して動的に作成する方法 .

手動で静的な順序に並べ替える

のように、要素を手動で並べ替えたい場合は、以下のようにします。 "foo", "bar", "baz" :

function cmp(array $a, array $b) {
    static $order = array('foo', 'bar', 'baz');
    return array_search($a['foo'], $order) - array_search($b['foo'], $order);
}


上記のすべてについて、もしあなたが PHP 5.3 以降を使用しているのなら (本当にそうすべきです)、 匿名関数を使用することでコードを短くし、 別のグローバル関数が浮遊するのを避けることができます。

usort($array, function (array $a, array $b) { return $a['baz'] - $b['baz']; });

このように、複雑な多次元配列を簡単にソートすることができるのです。もう一度言いますが 2つの項目のうちどちらが大きいかを判断する方法をPHPに教える。 実際のソートはPHPに任せてください。

また、上記すべてにおいて、昇順と降順を切り替えるには、単に $a$b の引数を囲む。例

return $a['baz'] - $b['baz']; // ascending
return $b['baz'] - $a['baz']; // descending

ある配列を別の配列で並べ替える

そして、一風変わった array_multisort これは、ある配列を別の配列に基づいて並べ替えることができます。

$array1 = array( 4,   6,   1);
$array2 = array('a', 'b', 'c');

ここで期待される結果は、次のようになる。

$array2 = array('c', 'a', 'b');  // the sorted order of $array1

使用方法 array_multisort をクリックすると、そこに行くことができます。

array_multisort($array1, $array2);

PHP 5.5.0以降では、以下のように使用できます。 array_column を使用すると、多次元配列からあるカラムを取り出し、そのカラムで配列を並べ替えることができます。

array_multisort(array_column($array, 'foo'), SORT_DESC, $array);

また、複数の列をそれぞれ左右に並べ替えることも可能です。

array_multisort(array_column($array, 'foo'), SORT_DESC,
                array_column($array, 'bar'), SORT_ASC,
                $array);

PHP 7.0.0 以降では、オブジェクトの配列からプロパティを抽出することもできます。


<ブロッククオート

<サブ もっとよくある事例があれば、この回答を自由に編集してください。