Array diff assoc: примеры (PHP)

Сравнение массивов с учётом ключей: array_diff_assoc
Раздел: Работа с массивами
array_diff_assoc(array $array, array ...$arrays): array

Основные сведения о array_diff_assoc

Назначение функции

Функция array_diff_assoc в языке PHP используется для сравнения массивов с учётом ключей. В отличие от array_diff, которая сравнивает только значения, array_diff_assoc проверяет и ключи, и значения. Она возвращает элементы из первого массива, отсутствующие во всех последующих массивах, при этом сравнение пар "ключ-значение" выполняется строгое.

Синтаксис и аргументы
array_diff_assoc(array $array, array ...$arrays): array

Функция принимает минимум два аргумента. Первый аргумент $array — это массив, с которым происходит сравнение. Второй и последующие аргументы $arrays — это массивы для сравнения с первым. Функция не имеет флагов.

Сравнение происходит в два этапа: сначала проверяется идентичность ключей (с помощью оператора ===), затем идентичность значений (также ===). Пары "ключ-значение" считаются равными только если они совпадают по типу и значению.

Простые примеры использования

Базовый пример сравнения двух массивов.

<?php
$array1 = ["a" => "green", "b" => "brown", "c" => "blue", "red"];
$array2 = ["a" => "green", "yellow", "red"];
$result = array_diff_assoc($array1, $array2);
print_r($result);
?>
Array
(
    [b] => brown
    [c] => blue
    [0] => red
)

Пример показывает, что сравниваются пары ключ-значение. Ключ "a" имеет одинаковое значение, поэтому не входит в результат. Элемент "red" из $array1 имеет ключ 0, а в $array2 значение "red" имеет ключ 1, поэтому оно включено в результат.

Сравнение более двух массивов
<?php
$arr1 = ["a" => 1, "b" => 2];
$arr2 = ["a" => 1, "b" => 3];
$arr3 = ["a" => 1];
$result = array_diff_assoc($arr1, $arr2, $arr3);
print_r($result);
?>
Array
(
    [b] => 2
)

Ключ "b" со значением 2 отсутствует в $arr2 (там значение 3) и в $arr3 (там такого ключа нет).

Похожие функции в PHP

Сравнивает массивы только по значениям, игнорируя ключи. Используется, когда важны только значения, а не их ассоциация с ключами.

Сравнивает массивы только по ключам. Возвращает элементы из первого массива, ключи которых отсутствуют во всех последующих массивах.

array_diff_uassoc

Позволяет задать пользовательскую функцию для сравнения ключей. Используется, когда требуется нестандартная логика сравнения индексов.

array_diff_ukey

Сравнивает массивы по ключам, используя пользовательскую функцию для их сравнения.

Функцию array_diff_assoc предпочтительно использовать, когда необходимо точное сравнение и ключей, и значений, например, для ассоциативных массивов, где ключ имеет смысловую нагрузку.

Распространённые ошибки

Непонимание строгого сравнения

Функция использует строгое сравнение (===), поэтому значения разного типа считаются разными.

<?php
$arr1 = ["a" => "1"]; // строка
$arr2 = ["a" => 1];   // целое число
$result = array_diff_assoc($arr1, $arr2);
print_r($result);
?>
Array
(
    [a] => 1
)

Несмотря на то что "1" и 1 равны при нестрогом сравнении, здесь они считаются разными.

Ожидание рекурсивного сравнения

Функция работает только на первом уровне вложенности.

<?php
$arr1 = ["a" => ["x" => 1]];
$arr2 = ["a" => ["x" => 1]];
$result = array_diff_assoc($arr1, $arr2);
print_r($result);
?>
Array
(
    [a] => Array
        (
            [x] => 1
        )

)

Вложенные массивы сравниваются как единое значение, а не рекурсивно.

Изменения в версиях PHP

Начиная с версии PHP 8.0.0, функция может быть вызвана без аргументов, что раньше приводило к ошибке. Теперь она возвращает пустой массив.

<?php
$result = array_diff_assoc([]);
print_r($result);
?>
Array
(
)

В PHP 7.x для вызова функции требовался минимум один аргумент, иначе возникало предупреждение.

Расширенные примеры

Сравнение массивов с числовыми и строковыми ключами

Ключи сравниваются строго, поэтому числовой ключ 0 и строковый "0" считаются разными.

Пример php
<?php
$arr1 = [0 => "a", "0" => "b", 1 => "c"];
$arr2 = [0 => "a"];
$result = array_diff_assoc($arr1, $arr2);
print_r($result);
?>
Array
(
    [0] => b
    [1] => c
)

Первый элемент с ключом 0 и значением "a" совпадает, поэтому исключён. Элемент с ключом "0" (строковым) остался, так как такого ключа нет в $arr2.

Работа с многомерными массивами

Для глубокого сравнения многомерных массивов требуется рекурсивный подход.

Пример php
<?php
function array_diff_assoc_recursive($array1, $array2) {
    $difference = [];
    foreach ($array1 as $key => $value) {
        if (is_array($value)) {
            if (!isset($array2[$key]) || !is_array($array2[$key])) {
                $difference[$key] = $value;
            } else {
                $recursiveDiff = array_diff_assoc_recursive($value, $array2[$key]);
                if (!empty($recursiveDiff)) {
                    $difference[$key] = $recursiveDiff;
                }
            }
        } elseif (!array_key_exists($key, $array2) || $array2[$key] !== $value) {
            $difference[$key] = $value;
        }
    }
    return $difference;
}

$arr1 = ["a" => ["x" => 1, "y" => 2], "b" => 3];
$arr2 = ["a" => ["x" => 1], "b" => 3];
$result = array_diff_assoc_recursive($arr1, $arr2);
print_r($result);
?>
Array
(
    [a] => Array
        (
            [y] => 2
        )

)
Использование с массивами, содержащими null и false
Пример php
<?php
$arr1 = ["a" => null, "b" => false];
$arr2 = ["a" => false, "b" => null];
$result = array_diff_assoc($arr1, $arr2);
print_r($result);
?>
Array
(
    [a] => 
    [b] => 
)

Оба элемента остались, так как null не равно false при строгом сравнении.

Аналоги в других языках программирования

Array diff assoc в Python

В Python нет прямой встроенной аналогии, но можно использовать словари (dict) и операции вычитания множеств ключей или генераторы.

dict1 = {"a": 1, "b": 2, "c": 3}
dict2 = {"a": 1, "b": 3}
result = {k: v for k, v in dict1.items() if (k, v) not in dict2.items()}
print(result)
{'b': 2, 'c': 3}

Array diff assoc в Javascript

В JavaScript для объектов нет прямой функции, но можно реализовать аналогичную логику.

const obj1 = {a: 1, b: 2, c: 3};
const obj2 = {a: 1, b: 3};
const result = {};
for (let key in obj1) {
    if (!(key in obj2 && obj1[key] === obj2[key])) {
        result[key] = obj1[key];
    }
}
console.log(result);
{ b: 2, c: 3 }

Array diff assoc в MySQL

В SQL нет прямого аналога для работы с массивами. Сравнение пар ключ-значение обычно выполняется через условия в запросах JOIN или WHERE.

PHP array_diff_assoc function comments

En
Array diff assoc Computes the difference of arrays with additional index check