PHP - 如何比较两个数组并删除重复的值

问题描述:

所以这是什么让我感到困扰。PHP - 如何比较两个数组并删除重复的值

我有两个数组:

$array1 = array('[param1]' ,'demo' ,'[param2]' ,'some' ,'[param3]'); 
$array2 = array('value1' ,'demo' ,'value2' ,'some' ,'value3'); 

现在我想比较这两个数组,并删除所有重复值。
最后我想要这两个数组,但没有“demo”和“some”值。
我想从数组中删除所有具有相同索引键和值的值。
数组总是有相同数量的值和索引,我只想比较它们并从两者中删除具有相同索引键和值的条目。

我现在做这样的事情:

$clean1 = array(); 
$clean2 = array();  

foreach($array1 as $key => $value) 
{ 
    if($value !== $array2[$key]) 
    { 
     $clean1[$key] = $value; 
     $clean2[$key] = $array2[$key]; 
    } 
} 

var_export($clean1); 
echo "<br />"; 
var_export($clean2); 

而这个作品!但即时通讯想知道有没有其他方式做到这一点?也许没有使用foreach循环?有没有更优雅的方式来做到这一点?

+3

你能定义什么是“优雅”吗?我在这里看到没有问题... – nmagerko 2012-01-01 01:04:46

+3

这总是需要线性搜索。在这方面,您的解决方案是最有效的解决方案。 – You 2012-01-01 01:05:46

array_unique(array_merge($arr_1, $arr_2)); 

,或者你可以这样做:

$arr_1 = array_diff($arr_1, $arr_2); 
$arr_2 = array_diff($arr_2, $arr_1); 

我猜...

+0

谢谢!第二个是“优雅”!但是,array_diff会取消arr_1中不存在于$ arr_2中的键,并使用不按顺序的键返回该数组。这对我来说可能是一个问题:(我需要从0开始的新数组:S有没有办法重置数组键,如果我有像0,3,7这样的键,我可以将它们重置为1,2, 3如果不是Il joust坚持使用第一个foreach循环 – Limeni 2012-01-01 01:22:26

+4

$ arr_1 = array_values($ arr_1);应该可以工作 – 2012-01-01 01:30:49

+0

yup不错,不能迭代愚蠢的PHP重循环xD – 2012-01-01 01:36:27

您可以使用PHP函数和array_diff将返回以及包含该之间的相同键数组两个阵列。

$clean1 = array_diff($array1, $array2); 

http://php.net/manual/en/function.array-diff.php

+0

谢谢!第二个是“优雅”! ,它array_diff从arr_1中取消了$ arr_2中不存在的键,这对我来说可能是一个问题:(我需要从0开始的新数组:S是否有任何方法可以重置数组键,如果我有键为0 ,3,7,我可以将它们重置为1,2,3? – Limeni 2012-01-01 01:23:36

由于$array1$array2总是相同的长度,你可以做这样的事情:

<?php 

    $array1 = array('[param1]' ,'demo' ,'[param2]' ,'some' ,'[param3]'); 
    $array2 = array('value1' ,'demo' ,'value2' ,'some' ,'value3'); 

    $map = array_combine($array1,$array2); 
    $map = array_filter($map ,function ($item) use (&$map) { 
     $keep_data = ($item != key($map)); 
     next($map); 
     return $keep_data; 
    }); 

    $clean1 = array_keys($map); 
    $clean2 = array_values($map); 

    var_export($clean1); 
    echo "<br />"; 
    var_export($clean2); 

?> 

是更好?你决定

+0

对于我来说,这一个更复杂一点,我认为我是用foreach循环做的矫枉过正,但它看起来就是这样做的最好方式。至少对我来说,对于你来说这个可以更清晰些。感谢评论! – Limeni 2012-01-01 01:31:23

+1

Yup ...同意......并且它也慢3倍:) – Dancrumb 2012-01-02 16:57:52

那么?

$res = array_diff($array1, $array_intersect($array1, $array2)); 
$reindexed = array_combine(array_keys($res), array_values($res)); 

或者干脆如果方法不需要钥匙

array_values(array_diff($array1, $array_intersect($array1, $array2))); 

$clean1 = array_diff($array1, $array2); 
$clean2 = array_diff($array2, $array1); 
$final_output = array_merge($clean1, $clean2); 
+1

请添加一些解释,让人们可以了解为什么这个工程 – jou 2015-03-02 01:05:22

您的解决方案绝对是最“优雅”(意为最简单的阅读,至少代码量),但在这里是另一种使用array_diff_ukey()的解决方案。它会保留这些密钥,并按照您的要求将它们按增量顺序放置。

$array1 = ['[param1]' ,'demo' ,'[param2]' ,'some' ,'[param3]']; 
$array2 = ['value1' ,'demo' ,'value2' ,'some' ,'value3']; 

$clean1 = $array1; 

$clean2 = array_diff_ukey(
    $array2, 
    $array1, 
    // Need to have "&" so the values get set. 
    function($a, $b) use (&$clean1, $array1, $array2) { 

     // Use isset() just in case keys are not identical 
     // or arrays are not the same length. 
     if (isset($array2[$b]) && $array2[$b] === $array1[$b]) { 
      unset($clean1[$b]); 
     } 

     return strcmp($array2[$a], $array1[$b]); 

}); 

print_r($clean1); 
print_r($clean2); 

将返回此:

Array 
(
    [0] => [param1] 
    [2] => [param2] 
    [4] => [param3] 
) 
Array 
(
    [0] => value1 
    [2] => value2 
    [4] => value3 
) 

工作实例here