array_unique($array)は、重複する値を取り除いた配列を返します。各値の最初の出現が元のキーのまま残り、あとのコピーは取り除かれます。
最初の結果はキー0, 1, 3を保っています。各値が最初に現れた位置です。json_encodeの前など、きれいなリストが欲しいときは、呼び出しをarray_values()で包みます。
array_uniqueが2つの値を同じとみなす基準
デフォルトでは、各値を文字列に変換して文字列どうしを比較します。そのため1、"1"、1.0は同じ値とみなされ、最初のものが残ります。2つ目の引数で比較方法を変えられます。
| フラグ | 2つの値が重複とみなされる条件 |
|---|---|
SORT_STRING(デフォルト) | (string) $a === (string) $b |
SORT_REGULAR | $a == $b |
SORT_NUMERIC | 数値として等しい |
デフォルトでは、文字列"01"は文字列"1"ではないので"01"が残ります。SORT_REGULARでは"01" == 1がtrueなので取り除かれます。ゆるい比較では、真偽値のtrueも空でないあらゆる値に一致します。型が混ざる場合は、結果を確認してから使いましょう。ルールは比較演算子のページで説明しています。
大文字小文字を無視して重複を取り除く
array_uniqueは大文字小文字を区別するので、"PHP"と"php"は別物です。これらを重複として扱いつつ最初のものの元の表記を残すには、小文字にしたコピーで一意なキーを見つけ、元の配列からそのキーを残します。
array_mapは同じキーを持つ小文字のコピーを作り、array_uniqueは最初の出現のキーを残し、array_intersect_keyは元の配列からそのキーを取り出します。アクセント付きの文字や日本語のテキストには、strtolowerの代わりにmb_strtolowerを使います。
多次元配列に対するarray_unique
フラグがないと、array_uniqueはすべての行を文字列"Array"に変換するので、すべての行が同じに見えて最初の行だけが残り、行ごとに「Array to string conversion」の警告が出ます。行全体を比較するにはSORT_REGULARを渡します。1つのフィールドの値ごとに1行を残すなら、nullとインデックスキーを指定したarray_columnのほうが簡単です。
2つ目の方法では、あとの行が同じキーの下で前の行を上書きするので、各メールアドレスの最後の行が残ります。インデックスキーについてはarray_columnのページで詳しく説明しています。
重複する値を見つけて数える
array_count_values()は、各値が何回現れるかを返します。それを1より大きい数で絞り込めば、重複がわかります。
最後の判定は、配列に重複があるかどうかを確かめるよく使われる1行です。
大きな配列で一意な値を速く得る
array_uniqueは比較の前にすべての値を文字列に変換しますが、数千個の値なら問題ありません。整数や文字列の大きなリストなら、配列を反転するほうが速くなります。値がキーになり、キーは定義上一意だからです。
時間は実行のたびに変わりますが、反転する方法はたいてい数倍速くなります。配列のキーになれる値(整数と文字列)にしか使えず、"5"のような数値の文字列は整数として返ってきます。
よくある質問
array_uniqueはキーを保ちますか?
保ちます。各値の最初の出現を元のキーのまま残し、あとの出現を取り除くので、キーには欠番ができることがあります。0から振り直すにはarray_values(array_unique($arr))を使います。
多次元配列でarray_uniqueを使うには?
行全体を比較するようSORT_REGULARを渡します:array_unique($rows, SORT_REGULAR)。メールアドレスごとに1行のように、あるフィールドの値ごとに1行だけ残すには、そのフィールドで行に索引を付けます:array_column($rows, null, 'email')は各メールアドレスの最後の行を残します。
大文字小文字を無視して重複を取り除くには?
小文字にしたコピーで一意なキーを見つけ、元の配列からそのキーを残します:array_intersect_key($arr, array_unique(array_map('strtolower', $arr)))。ASCII以外のテキストにはmb_strtolowerを使います。
PHPの配列でどの値が重複しているかを見つけるには?
array_count_values($arr)で数え、1より大きいものを残します:array_keys(array_filter(array_count_values($arr), fn($n) => $n > 1))。array_count_valuesは文字列と整数にしか使えません。