Menu

PHPの配列のソート:sort()、usort()、asort()、ksort()

sort($array)はリストをその場で並べ替え、asortとksortは連想配列を値やキーで並べ替え、usortは独自の比較で並べ替えます。それぞれの使い方、多次元配列の列による並べ替え、定番の$sorted = sort($arr)のミスの避け方を学びます。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

sort($array)は配列をその場で昇順に並べ替えます。渡した変数を変更してtrueを返すので、単独の行で呼び出してから配列を使います。rsort()は降順に並べ替えます。

PHPには、「値かキーか」「昇順か降順か」「キーを保つかどうか」の組み合わせごとにソート関数があります。

関数並べ替えの基準順番キー
sort値昇順0, 1, 2と振り直す
rsort値降順振り直す
asort値昇順保つ
arsort値降順保つ
ksortキー昇順保つ
krsortキー降順保つ
usort自分の関数自由振り直す
uasort自分の関数自由保つ
uksortキーに対する自分の関数自由保つ

連想配列を値で並べ替える

連想配列にsort()を使うとキーが消えます。値で並べ替えて各キーを値と結びつけたまま保つにはasort()を、大きい順ならarsort()を使います。

ksortで配列をキーで並べ替える

ksort()はキーの順に、krsort()はキーの逆順に並べます。設定を出力したり、クエリ文字列を一定の順番で組み立てたりする前に便利です。

usortと宇宙船演算子で独自の順番にする

usort($array, $callback)を使えば順番を自分で決められます。コールバックは2つの要素を受け取り、1つ目を先にするなら負の数、2つ目を先にするなら正の数、等しければ0を返します。宇宙船演算子<=>はまさにそれを返します。

bananaとcherryは同じ長さなので、コールバックは0を返し、すでにあった順番のままになります。PHPのソートはPHP 8.0以降安定で、等しい要素は前の順番を保ちます。

多次元配列を値で並べ替える

行のリストを1つのフィールドで並べ替えるには、usortでそのフィールドを比較します。2つのフィールドで並べ替えるには配列を比較します。<=>は要素ごとに比較するので、2つ目のフィールドは1つ目が同じときだけ順番を決めます。

2つ目の比較では、$b["age"]を左側に、$a["age"]を右側に置いているので、年齢の順番だけが逆になります。array_multisort(array_column($people, 'city'), SORT_ASC, array_column($people, 'age'), SORT_DESC, $people)でも、コールバックなしで同じ順番になります。取り出した列で並べ替え、それに合わせて$peopleを並べ直すのです。

自然順とソートフラグ

デフォルトでは、PHPは数値を数値として、文字列を文字列として比較します。数字を含むファイル名は、人が予想しない順番に並びます。img10がimg2より前に来て、大文字の名前がすべて小文字の名前より前に来ます。フラグで値の比較方法を変えられます。

SORT_NATURALは連続した数字を数値として読み、SORT_FLAG_CASEは大文字小文字を無視し、SORT_STRINGは数値の文字列でも1文字ずつの比較を強制します。natsort()とnatcasesort()は同じ考え方で、キーを保ちます。

よくあるミス:sortの結果を代入する

すべてのソート関数はtrueを返し、渡した配列を変更します。戻り値を代入すると配列を失います。

元の配列を残したまま並べ替えたコピーが必要なら、上のasortの例で$copyを使っているように、先に配列を新しい変数にコピーしてからコピーを並べ替えます。

よくある質問

sort()が並べ替えた配列ではなくtrueを返すのはなぜですか?

PHPのソート関数は、参照を通して配列をその場で並べ替え、trueを返します。sort($arr);を単独の行で呼び、そのあと$arrを使います。$arr = sort($arr);と書くと、配列がtrueに置き換わります。

連想配列を値で並べ替えてキーを保つには?

昇順ならasort($arr)、降順ならarsort($arr)を使います。sort()とrsort()も値で並べ替えますが、キーを捨てて0から番号を振り直します。

PHPで多次元配列を値で並べ替えるには?

フィールドに宇宙船演算子を使うusortを使います:usort($rows, fn($a, $b) => $a['age'] <=> $b['age']);。降順なら$aと$bを入れ替え、2つのフィールドで並べ替えるなら[$a['city'], $a['age']] <=> [$b['city'], $b['age']]のように配列を比較します。

PHPのソートは安定ですか?

はい。PHP 8.0以降、すべてのソート関数は安定です。等しいと比較された要素は、並べ替える前の順番を保ちます。1つのフィールドで並べ替えてから別のフィールドで並べ替える処理が期待どおりに動くのはこのためです。

数字を含む文字列を自然な順番で並べ替えるには?

natsort($arr)かsort($arr, SORT_NATURAL)を使うと、img2がimg10より前になります。大文字小文字を無視するにはSORT_FLAG_CASEを加える(SORT_NATURAL | SORT_FLAG_CASE)か、natcasesortを使います。

Coddyのプログラミング言語のイラスト

Coddyでコードを学ぼう

始める