Reputation: 5224
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?
Upvotes: 28
Views: 69183
Reputation: 1312
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);
Upvotes: 50
Reputation: 47894
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'];
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
.
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.
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
)
]);
Upvotes: 1
Reputation: 2733
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
Upvotes: 2