array_unique($array) возвращает массив без повторяющихся значений. Первое вхождение каждого значения остаётся под исходным ключом, а последующие копии отбрасываются.
Первый результат сохраняет ключи 0, 1, 3: позиции, где каждое значение встретилось впервые. Оберните вызов в array_values(), когда нужен чистый список, например перед json_encode.
Как array_unique решает, что значения одинаковые
По умолчанию каждое значение приводится к строке, и сравниваются строки. Поэтому 1, "1" и 1.0 считаются одним значением, и побеждает первое. Второй аргумент меняет способ сравнения.
| Флаг | Значения считаются дубликатами, когда |
|---|---|
SORT_STRING (по умолчанию) | (string) $a === (string) $b |
SORT_REGULAR | $a == $b |
SORT_NUMERIC | они равны как числа |
По умолчанию "01" остаётся, потому что строка "01" не равна строке "1". С SORT_REGULAR оно отбрасывается, потому что "01" == 1 истинно. Нестрогое сравнение ещё и позволяет логическому true совпасть с любым непустым значением. Со смешанными типами проверяйте вывод, прежде чем на него полагаться; правила объяснены на странице об операторах сравнения.
Удаление дубликатов без учёта регистра
array_unique учитывает регистр: "PHP" и "php" разные. Чтобы считать их дубликатами, но сохранить исходное написание первого, найдите уникальные ключи на копии в нижнем регистре и оставьте эти ключи из оригинала.
array_map строит копию в нижнем регистре с теми же ключами, array_unique оставляет ключи первых вхождений, а array_intersect_key выбирает эти ключи из исходного массива. Для текста с диакритикой или японского используйте mb_strtolower вместо strtolower.
array_unique для многомерного массива
Без флага array_unique приводит каждую строку к строке "Array", поэтому все строки выглядят одинаково и остаётся только первая, а для каждой строки выдаётся предупреждение "Array to string conversion". Передайте SORT_REGULAR, чтобы сравнивать строки целиком. Чтобы оставить одну строку на значение одного поля, проще array_column с null и ключом индекса.
Второй способ оставляет последнюю строку для каждого email, потому что каждая следующая строка перезаписывает предыдущую под тем же ключом. Ключ индекса подробно объяснён на странице array_column.
Поиск и подсчёт повторяющихся значений
array_count_values() возвращает, сколько раз встречается каждое значение. Отфильтруйте счётчики больше единицы, и получите дубликаты.
Последняя проверка это распространённый однострочник, который выясняет, есть ли в массиве дубликаты вообще.
Быстрые уникальные значения для больших массивов
array_unique приводит каждое значение к строке перед сравнением, и для тысяч значений это нормально. Для большого списка целых чисел или строк быстрее перевернуть массив: значения становятся ключами, а ключи уникальны по определению.
Время меняется от запуска к запуску, но вариант с переворотом обычно в несколько раз быстрее. Он работает только для значений, которые могут быть ключами массива (целые числа и строки), а числовые строки вроде "5" возвращаются целыми числами.
Часто задаваемые вопросы
Сохраняет ли array_unique ключи?
Да. Функция оставляет первое вхождение каждого значения под исходным ключом и отбрасывает последующие, поэтому в ключах могут быть пропуски. Используйте array_values(array_unique($arr)), чтобы перенумеровать их с 0.
Как использовать array_unique для многомерного массива?
Передайте SORT_REGULAR, чтобы сравнивались целые строки: array_unique($rows, SORT_REGULAR). Чтобы оставить одну строку на значение поля, например одну строку на email, проиндексируйте строки по этому полю: array_column($rows, null, 'email') оставляет последнюю строку для каждого email.
Как удалить дубликаты без учёта регистра?
Найдите уникальные ключи на копии в нижнем регистре и оставьте эти ключи из оригинала: array_intersect_key($arr, array_unique(array_map('strtolower', $arr))). Для текста за пределами ASCII используйте mb_strtolower.
Как найти повторяющиеся значения в массиве PHP?
Посчитайте их через array_count_values($arr) и оставьте счётчики больше единицы: array_keys(array_filter(array_count_values($arr), fn($n) => $n > 1)). array_count_values работает только со строками и целыми числами.