Разработчику. Сборник рецептов PHP
Задавайте вопросы

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

Вернуться назад

Задача

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

Решение

Для определения объединения:

$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.

Вернуться назад

Рейтинг@Mail.ru

Яндекс.Метрика

Индекс цитирования


Рейтинг Сайтов ДОСКИ.РУ