Есть два массива, и требуется найти их объединение (все элементы, но если элемент входит в оба массива, он учитывается один раз), пересечение (элементы, входящие в оба массива) или разность (элементы одного массива, не присутствующие в другом).
Для определения объединения:
$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(), так как эти массивы были специально сконструированы как не имеющие общих элементов.
См. также
Документацию по функции array_unique() на http://www.php.net/array-unique, по функции array_intersect() на http://www.php.net/array-intersect, по функции array_diff() на http://www.php.net/array-diff, по функции array_merge() на http://www.php.net/array-merge и по функции array_map() на http://www.php.net/array-map.