Я использую array_diff (), чтобы принимать значения из array1, которые находятся в array2. Проблема в том, что он удаляет все вхождения из array1, как отмечает документация PHP. Я хочу, чтобы он снимал только по одному.
$array1 = array(); $array1[] = 'a'; $array1[] = 'b'; $array1[] = 'a'; $array2 = array(); $array2[] = 'a';
Он должен возвращать массив с одним «a» и «b» вместо массива с «b»;
Просто для удовольствия, что-то, что просто пришло в голову. Будет работать до тех пор, пока ваши массивы содержат строки:
$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) );