我正在使用array_diff()从array1中的array1中获取值。问题是它会从array1中删除所有出现的内容,正如PHP文档所记录的那样。我希望它一次只取出一个。
$array1 = array();
$array1[] = 'a';
$array1[] = 'b';
$array1[] = 'a';
$array2 = array();
$array2[] = 'a';
它应该返回一个数组,其中包含一个' a'和一个'而不是只有' b'的数组;
答案 0 :(得分:11)
只是为了它的乐趣,一些刚想到的东西。只要您的数组包含字符串,就可以工作:
$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]--;
});
它的优势在于它只能遍历每个阵列一次。
<强> See it in action 强>
工作原理:
首先计算第二阵列中每个元素的频率。这给了我们一个数组,其中键是应该从$a
中删除的元素,值是每个元素应该被删除的次数。
然后使用array_filter
逐个检查$a
的元素,并删除那些应删除的元素。如果没有等于被检查项目的密钥或者该项目的剩余删除计数达到零,则过滤函数使用empty
返回true
; empty
的行为完全适合这项法案。
如果以上都不成立,那么我们想要返回false
并将删除计数减一。使用false || !$counts[$o]--
是一个技巧,为了简洁:它递减计数并始终计算为false
,因为我们知道计数开始时大于零(如果不是,{{1在评估||
)之后会发生短路。
答案 1 :(得分:5)
编写一些从第一个数组中逐个删除元素的函数,如:
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) );