Хранить дубликаты при использовании array_diff

Я использую array_diff (), чтобы принимать значения из array1, которые находятся в array2. Проблема в том, что он удаляет все вхождения из array1, как отмечает документация PHP. Я хочу, чтобы он снимал только по одному.

$array1 = array(); $array1[] = 'a'; $array1[] = 'b'; $array1[] = 'a'; $array2 = array(); $array2[] = 'a'; 

Он должен возвращать массив с одним «a» и «b» вместо массива с «b»;

Related of "Хранить дубликаты при использовании array_diff"

Просто для удовольствия, что-то, что просто пришло в голову. Будет работать до тех пор, пока ваши массивы содержат строки:

 $a = array('a','b','a','c'); $b = array('a'); $counts = array_count_values($b); $a = array_filter($a, function($o) use (&$counts) { return empty($counts[$o]) || !$counts[$o]--; }); 

Преимущество состоит в том, что он только один раз перебирает каждый из ваших массивов.

Смотрите в действии .

Как это работает:

Сначала подсчитываются частоты каждого элемента во втором массиве. Это дает нам массивы, где ключи – это элементы, которые должны быть удалены из $a а значения – это количество раз, которое должен удалять каждый элемент.

Затем array_filter используется для проверки элементов $a один за другим и удаления тех, которые должны быть удалены. Функция фильтра использует empty для возврата true если нет ключа, равного проверяемому элементу, или если оставшееся количество удаления для этого элемента достигло нуля; empty поведение отлично подходит для счета.

Если ни одно из указанных выше не выполняется, мы хотим вернуть значение false и уменьшить количество удаления на единицу. Использование false || !$counts[$o]-- false || !$counts[$o]-- это трюк, чтобы быть кратким: он уменьшает счетчик и всегда вычисляет false потому что мы знаем, что счетчик был больше нуля, чтобы начать (если бы это было не так, || коротко -схема после оценки empty ).

Напишите некоторую функцию, которая удаляет элементы из первого массива один за другим, например:

 function array_diff_once($array1, $array2) { foreach($array2 as $a) { $pos = array_search($a, $array1); if($pos !== false) { unset($array1[$pos]); } } return $array1; } $a = array('a', 'b', 'a', 'c', 'a', 'b'); $b = array('a', 'b', 'c'); print_r( array_diff_once($a, $b) ); с function array_diff_once($array1, $array2) { foreach($array2 as $a) { $pos = array_search($a, $array1); if($pos !== false) { unset($array1[$pos]); } } return $array1; } $a = array('a', 'b', 'a', 'c', 'a', 'b'); $b = array('a', 'b', 'c'); print_r( array_diff_once($a, $b) );