Keep duplicates when using array_diff

I use array_diff () to get the values ​​from array1 which are in array2. The problem is that it removes all occurrences from array1, as the PHP documentation notes. I want him to take out only one at a time.

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

It should return an array with one "a" and "b" instead of an array with "b";

+6
source share
2 answers

Just for fun, something that just occurred to me. Will work as long as your arrays contain strings:

 $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]--; }); 

The advantage is that it only iterates over each of your arrays only once.

Look at the action .

How it works:

First, the frequencies of each element in the second array are taken into account. This gives us arrays where the keys are the elements that should be removed from $a , and the values ​​are the number of times each element should delete.

array_filter is then used to examine $a elements one at $a and remove those that should be removed. The filter function uses empty to return true if there is no key equal to the element being checked, or if the remaining deletion amount for this element has reached zero; empty behavior is great for counting.

If none of the above is true, we want to return false and reduce the amount of deletion by one. Using false || !$counts[$o]-- false || !$counts[$o]-- is a trick to be brief: it decreases the counter and always evaluates to false , because we know that the counter was greater than zero to start (if it weren’t, || would be short-circuited after evaluating empty ).

+9
source

Write some function that removes elements from the first array one by one, something like:

 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) ); 
+5
source

Source: https://habr.com/ru/post/946733/


All Articles