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

时间:2012-01-01 00:59:15

标签: php arrays

所以这是困扰我的。

我有两个数组:

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

现在我要比较这两个数组,并删除所有重复的值 最后我想要这两个数组,但没有'demo'和'some'值 我想从array-s中删除具有相同索引键和值的所有值 Array将始终具有相同数量的值和索引,我只想比较它们并从两者中删除具有相同索引键和值的条目。

我现在正在做这样的事情:

$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循环?有更优雅的方式吗?

7 个答案:

答案 0 :(得分:28)

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

或者你可以这样做:

$arr_1 = array_diff($arr_1, $arr_2);
$arr_2 = array_diff($arr_2, $arr_1);
我猜...

答案 1 :(得分:4)

您可以在PHP中使用函数array_diff,它将返回包含两个数组之间相同键的数组。

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

您的解决方案绝对是最优雅的#34; (意思是最容易阅读,代码最少),但这是另一种使用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

答案 4 :(得分:0)

由于$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);

?>

更好吗?你决定

答案 5 :(得分:0)

怎么样?

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

答案 6 :(得分:0)

没有比使用标准foreach()循环更优雅的方式来处理两个数组。寻求功能上的等效项只会导致不必要的代码卷积。无需回避迭代构造-它不会使您看起来像“基本编码器”,它表明您知道解决问题的最简洁,最易读的方法。

还有太多其他答案没有尊重索引值关系!

最终,您的问题的答案是:完全保持您的代码不变。

这是如何通过函数编程分别处理每个数组({array_diff_ukey()是不必要的,而array_merge()的任何其他答案都是对这个问题的误解)。

代码:(Demo

$arr_1 = ['[param1]', 'remove', 'demo', '[param2]', 'some', '[param3]'];
$arr_2 = ['value1',   'remove', 'some', 'value2',   'demo', 'value3'];

var_export(
    array_filter(
        $arr_1,
        function($value, $index) use ($arr_2) {
            return $arr_2[$index] !== $value;
        },
        ARRAY_FILTER_USE_BOTH
    )
);

echo "\n---\n";

var_export(
    array_filter(
        $arr_2,
        function($value, $index) use ($arr_1) {
            return $arr_1[$index] !== $value;
        },
        ARRAY_FILTER_USE_BOTH
    )
);

echo "\n---\n";

var_export(
    array_diff_assoc($arr_1, $arr_2)
);

echo "\n---\n";

var_export(
    array_diff_assoc($arr_2, $arr_1)
);

也就是说,如果您对基于构造的迭代有不自然的偏见,则可以使用这些单线,但是它们将在后台执行您数据的4个单独的迭代,而foreach()仅执行一次

代码:(Demo

var_export(
    [
        'clean1' => array_values(array_diff_assoc($arr_1, $arr_2)),
        'clean2' => array_values(array_diff_assoc($arr_2, $arr_1))
    ]
);