如何从两个具有相同键和值的数组中删除值?

27

我有两个数组:

$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
这将始终需要进行线性搜索,在这方面上,你的解决方案是最有效的。 - You
这个问题不清楚,因为[mcve]质量太差了。 逻辑语句“I want to remove all values from array-s that have the same index key and value.”在示例数据中没有很好地表示出来。 这导致发布了不适当尊重索引值关系的答案。 - mickmackusa
3个回答

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

或者您可以这样做:

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

3
这个答案是不正确的,因为它会删除即使键不同也有相同值的元素。问题要求如何删除具有相同键和值的项。结果应该是两个数组,其中具有相同键和值的元素已被从它们中删除。 - Dharman

2

谢谢!第二个方法确实很“优雅”!但是,array_diff会从arr_1中删除在$arr_2中不存在的键。这对我来说可能是个问题:( 我需要一个新的数组,它从0开始:S 有没有办法重置数组键,如果我的键是0、3、7,我能把它们重置为1、2、3吗? - Limeni
2
这将删除第一个参数数组中的唯一元素。 - Jovylle
2
这个答案是不正确的,因为即使键值不同,它也会删除值。问题要求删除具有相同键和值的项。 - Dharman

1

简而言之: 如果你的数组大小相同且键值相同,则使用foreach()可以获得最佳性能。如果你喜欢简洁的函数式代码并且只需要松散比较,则使用array_diff_assoc()。如果你喜欢函数式代码并且需要严格比较,则使用array_filter()


这个答案将使用以下新的示例数据来澄清所需的行为:
$array1 = ['keepThis', 'remove', false, 'keep',   'save', 'delete'];
$array2 = ['hangOnto', 'remove', null,  'retain', 'keep', 'delete'];

由于数组中索引为[1]的值相同,这些值不会被存储在清理后的数组(remove)中。对于索引为[5] (delete)的元素也是如此。虽然keep在两个数组中都存在,但元素没有共享相同的索引/键。

正确的结果应该是:

$clean1 = [0 => 'keepThis', 2 => false, 3 => 'keep', 4 => 'save'];
$clean2 = [0 => 'hangOnto', 2 => null, 3 => 'retain', 4 => 'keep'];

  1. The asker's foreach() loop enjoys the benefit of having the smallest time complexity because it only traverses the first array just one time. However, if the array might not have the same count or keyed elements, then that code risks generating Warnings at $array2[$key] or not fully populating $clean2.

  2. array_diff_assoc() offers a concise functional approach, but only implements loose comparisons (if it matters): (Demo)

    var_export([
        array_diff_assoc($array1, $array2),
        array_diff_assoc($array2, $array1)
    ]);
    

    Bad Result (because false is loosely equal to null):

    [
        [0 => 'keepThis', 3 => 'keep', 4 => 'save'],
        [0 => 'hangOnto', 3 => 'retain', 4 => 'keep'],
    ]
    

    You can try to overcome the PHP core algorithm for array_diff_uassoc(), but this will either be unstable or prohibitively over-complicated.

  3. array_filter() is able to make strict comparisons and is not horribly verbose thanks to PHP7.4's arrow function syntax. (Demo)

    var_export([
        array_filter(
            $array1,
            fn($value, $index) => $array2[$index] !== $value,
            ARRAY_FILTER_USE_BOTH
        ),
        array_filter(
            $array2,
            fn($value, $index) => $array1[$index] !== $value,
            ARRAY_FILTER_USE_BOTH
        )
    ]);
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接