Определение объединения, пересечения или разности двух массивов

Задача
Есть два массива, и требуется найти их объединение (все элементы, но если элемент входит в оба массива, он учитывается один раз), пересечение (элементы, входящие в оба массива) или разность (элементы одного массива, не присутствующие в другом).

Решение
Для определения объединения:
$union = array_unique(array_merge($a, $b));

Для вычисления пересечения:
$intersection = array_intersection($a, $b);

Для нахождения простой разности:
$difference = array_diff($a, $b);

И для получения симметрической разности (исключающее ИЛИ):
$difference = array_merge(array_diff($a, $b), array_diff($b, $a));

Обсуждение
Многие из необходимых для таких вычислений компонентов встроены в PHP, нужно только объединить их в соответствующей последовательности.

При получении объединения из двух массивов создается один гигантский массив со всеми значениями исходных массивов. Но функция array_merge() разрешает дубликаты значений при объединении двух числовых массивов, поэтому нужно вызвать функцию array_unique(),
чтобы отфильтровать такие элементы.


Но при этом могут образоваться пропуски, поскольку функция array_unique() не уплотняет массив. Однако это не представляет затруднения, поскольку и оператор foreach, и функция each() без помех обрабатывают редко заполненные массивы.

Функция для вычисления пересечения имеет простое имя array_intersection() и не требует дополнительных усилий.

Функция array_diff() возвращает массив, содержащий все уникальные элементы массива $old, которые не входят в массив $new. Это называется простой разностью:
$old = array('To', 'be', 'or', 'not', 'to', 'be');
$new = array('To', 'be', 'or', 'whatever');
$difference = array_diff($old, $new);
Array
(
[3] => not
[4] => to
)

Результирующий массив $difference содержит 'not' и 'to', так как функция array_diff() чувствительна к регистру. В него не входит элемент 'whatever', поскольку его нет в массиве $old.

Чтобы получить обратную разность, или, другими словами, найти уникальные элементы массива $new, отсутствующие в массиве $old, нужно поменять местами аргументы:
$old = array('To', 'be', 'or', 'not', 'to', 'be');
$new = array('To', 'be', 'or', 'whatever');
$reverse_diff = array_diff($new, $old);
Array
(
[3] => whatever
)

Массив $reverse_diff содержит только элемент 'whatever'.

Если нужно применить функцию или другой фильтр в функции array_diff(), встройте свой собственный алгоритм нахождения разности (вычитания):

// применим нечувствительный к регистру алгоритм вычитания; разность -i
$seen = array();
foreach ($new as $n) {
$seen[strtolower($n)]++;
}
foreach ($old as $o) {
$o = strtolower($o);
if (!$seen[$o]) { $diff[$o] = $o; }
}

Первый оператор foreach создает ассоциативный массив для дальнейшего поиска.


Затем выполняется цикл по массиву $old и, если в процессе поиска элемент не найден, то он добавляется в массив $diff.

Этот процесс можно ускорить, объединив функции array_diff() и array_map():

$diff = array_diff(array_map('strtolower', $old),
array_map('strtolower', $new));

Симметрическая разность – это то, что принадлежит $a, но не принадлежит $b, плюс то, что есть в $b, но нет в $a:

$difference = array_merge(array_diff($a, $b), array_diff($b, $a));

Однажды установленный, алгоритм движется вперед. Функция array_diff() вызывается дважды и определяет две разности. Затем они объединяются в один массив. Нет необходимости вызывать функцию array_unique(), так как эти массивы были специально сконструированы как не имеющие общих элементов.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Добавление одного массива к другому
Изменение длины массива
Инициализация массива диапазоном
Инициализация массива диапазоном целых чисел
Нахождение всех перестановок массива

Вернуться в раздел: PHP / 4. Массивы