Функция array_diff_uassoc() в PHP
Узнайте, как работает array_diff_uassoc() в PHP: сравнение массивов с пользовательской функцией для ключей, примеры и связанные функции.
array_diff_uassoc() сравнивает два (или более) массива с дополнительной проверкой ключей и позволяет задать собственную функцию для их сравнения. Функция возвращает все элементы первого массива, пара ключ/значение которых не найдена ни в одном из остальных массивов. На этой странице описана сигнатура функции, подробно объясняется принцип сравнения и рассказывается, когда стоит использовать её вместо более простых функций для работы с разностью массивов.
Буква «u» в названии означает пользовательскую функцию сравнения ключей, а «assoc» указывает на то, что ключи тоже проверяются (ассоциативное сравнение).
Сигнатура
array_diff_uassoc(
array $array,
array ...$arrays,
callable $key_compare_func
): array$array— array, из которого производится сравнение. Его элементы попадают в результат.$arrays— один или несколько массивов, с которыми производится сравнение.$key_compare_func— коллбэкfn(mixed $a, mixed $b): int, возвращающий0, когда два ключа считаются равными, и отрицательное/положительное целое число в противном случае (тот же контракт<=>, что используется вusort). Встроенные функции, напримерstrcasecmp, подходят по этому интерфейсу.
Функция возвращает новый array; исходные массивы не изменяются.
Как работает сравнение
Именно здесь чаще всего возникают ошибки. array_diff_uassoc() оставляет элемент из $array только если для него оба условия выполняются относительно остальных массивов:
- Значение не совпадает (значения сравниваются по обычному нестрогому правилу
==после приведения к string — то же правило, что используетarray_diff()), или - Ключ не совпадает согласно вашей
$key_compare_func.
Иными словами: элемент удаляется только тогда, когда в другом массиве есть то же значение под ключом, который ваш коллбэк считает равным. Таким образом, пользовательский коллбэк управляет только ключами; значения по-прежнему сравниваются встроенным правилом PHP. Это самое распространённое заблуждение — коллбэк предназначен только для ключей.
Пример
Сравнение прайс-листов с ключами без учёта регистра
Вывод:
Array
(
[Banana] => 0.5
[Cherry] => 3
)Разберём каждый элемент $prices:
Apple => 1.20—strcasecmp("Apple", "apple")равно0, значит ключи совпадают, и значение1.20тоже совпадает с$updated["apple"]. Оба совпадают, поэтому элемент удаляется.Banana => 0.50— ключи совпадают (strcasecmp("Banana", "banana") === 0), но значения различаются (0.50и0.75). Поскольку значение не совпадает, элемент оставляется.Cherry => 3.00— ни один ключ в$updatedне совпадает, поэтому элемент оставляется.
Это наглядно демонстрирует правило: совпадения только по ключу недостаточно для удаления элемента — значение тоже должно совпасть.
Связанные функции разности массивов
array_diff_uassoc() входит в семейство функций для вычисления разности массивов. Выбирайте ту, чья стратегия сравнения соответствует вашим данным:
array_diff()— сравнивает только значения; ключи игнорируются.array_diff_assoc()— сравнивает ключи и значения по встроенным правилам (без коллбэков).array_diff_key()— сравнивает только ключи по встроенному правилу.array_diff_ukey()— сравнивает только ключи, но с коллбэком для их сравнения.array_udiff()— сравнивает значения с помощью коллбэка; ключи игнорируются.array_udiff_assoc()— коллбэк для значений, встроенная проверка ключей.array_udiff_uassoc()— коллбэки для значений и ключей одновременно.
Когда стоит использовать эту функцию?
Используйте array_diff_uassoc(), когда ключи важны для сравнения, но стандартное сопоставление слишком строгое — например, когда ключи различаются только регистром или форматированием, либо когда ключи являются объектами или значениями, требующими пользовательской логики для признания «равными». Если вас интересуют только значения, используйте array_udiff(); если нужен коллбэк и для значений, используйте array_udiff_uassoc().
Заключение
array_diff_uassoc() возвращает элементы первого массива, для которых не найдено совпадения по паре ключ/значение ни в одном из остальных массивов, используя переданный вами коллбэк для определения равенства ключей. Помните, что значения по-прежнему сравниваются встроенным правилом PHP — элемент остаётся в результате, если не совпадают одновременно и его ключ, и его значение.