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



我有两个数组:

$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循环?

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

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

$clean1 = array_diff($array1, $array2);
http://php.net/manual/en/function.array-diff.php

TL;DR:如果您的数组具有相同的大小和相同的键,则使用foreach()以获得最佳性能。如果您更喜欢简洁、实用的代码,并且只需要松散的比较,请使用array_diff_assoc()。如果你更喜欢函数式代码,并且需要严格的比较,那么使用array_filter()


这个答案将使用以下新的示例数据来阐明所需的行为:

$array1 = ['keepThis', 'remove', false, 'keep',   'save', 'delete'];
$array2 = ['hangOnto', 'remove', null,  'retain', 'keep', 'delete'];

因为数组(remove)中索引[1]处的值是相同的,所以这些值不会存储在干净数组中。索引为[5] (delete)的元素也是如此。虽然在两个数组中都可以找到keep,但元素不共享相同的索引/键。

正确的结果应该是:
$clean1 = [0 => 'keepThis', 2 => false, 3 => 'keep', 4 => 'save'];
$clean2 = [0 => 'hangOnto', 2 => null, 3 => 'retain', 4 => 'keep'];

  1. 请求程序的foreach()循环具有最小的时间复杂度,因为它只遍历第一个数组一次。但是,如果数组可能没有相同的计数或键值元素,那么该代码可能会在$array2[$key]处生成警告或未完全填充$clean2

  2. array_diff_assoc()提供了一个简洁的功能方法,但只实现了松散的比较(如果重要的话):(Demo)

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

    错误结果(因为false松散地等于null):

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

    您可以尝试克服array_diff_uassoc()的PHP核心算法,但这要么不稳定,要么过于复杂。

  3. array_filter()能够进行严格的比较,并且由于PHP7.4的箭头函数语法而不是可怕的冗长。(演示)

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

最新更新