26

I have two arrays:

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

I want to compare these two arrays and remove all duplicate values.
In the end, I want these two arrays but without 'demo' and 'some' values in them.
I want to remove all values from arrays that have the same index key and value.
Arrays will always have the same number of values and indexes, I only want to compare them and remove entries that have the same index key and value, from both of them.

I'm doing something like this now:

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

And this works! But I'm wondering is there any other way of doing this? Maybe without using foreach loop?

Dharman
  • 30,962
  • 25
  • 85
  • 135
Limeni
  • 4,954
  • 8
  • 31
  • 33
  • 3
    This is always going to require a linear search. In that regard, your solution is the most efficient one. – You Jan 01 '12 at 01:05
  • This question is Unclear because the [mcve] is too poor in quality. The logical statement of `I want to remove all values from array-s that have the same index key and value.` is not well represented in the sample data. This has led to the posting of answers that do not suitably respect index-value relationships. – mickmackusa Aug 18 '20 at 22:40

3 Answers3

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

or you can do:

$arr_1_final = array_diff($arr_1, $arr_2);
$arr_2_final = array_diff($arr_2, $arr_1);
doitlikejustin
  • 6,293
  • 2
  • 40
  • 68
Mr. BeatMasta
  • 1,265
  • 10
  • 10
  • 3
    This answer is incorrect because it will remove values even if the keys are different. The question asked how to remove items that have the same key and value. The outcome should be two arrays that have the elements with the same key and value removed from them. – Dharman Apr 15 '22 at 14:12
1

TL;DR: If your arrays have the same size and identical keys, then use foreach() for best performance. If you prefer concise, functional code and only need loose comparisons, use array_diff_assoc(). If you prefer functional code and need strict comparisons, then use array_filter().


This answer will use the following new sample data to clarify the required behavior:

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

Because the values at index [1] in the arrays (remove) are identical these values will not be stored in the clean arrays. The same is true for the elements with an index of [5] (delete). Although keep is found in both arrays, the elements do not share the same indices/keys.

The correct result should be:

$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
        )
    ]);
    
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
1

You can use the function array_diff in PHP that will return and array containing the keys that are the same between the two arrays.

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

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

Shawn Janas
  • 2,693
  • 2
  • 14
  • 10
  • Thanks! The second one is "elegant"! But, it array_diff unsets keys from arr_1 that are not present in $arr_2. And this can be a problem for me :( I need new array that starts from 0 :S Is there any way to reset array keys, if I have keys like 0, 3, 7, can I reset them to be 1,2,3? – Limeni Jan 01 '12 at 01:23
  • 2
    This will remove the unique elements in the first parameter array. – Jovylle Apr 20 '21 at 12:23
  • 2
    This answer is incorrect because it will remove values even if the keys are different. The question asked how to remove items that have the same key and value. – Dharman Apr 15 '22 at 14:13