I have 2 arrays that look like this:
$array1 = [
['id' => '434b5g6', 'unique_id' => 'banana', 'level' => 8],
['id' => 'bfrfnr', 'unique_id' => 'apple', 'level' => 4],
['id' => 'yt347509', 'unique_id' => 'grapefruit', 'level' => 9],
['id' => '456645', 'unique_id' => 'strawberry', 'level' => 1],
];
$array2 = [
['id' => 'gon235g6', 'unique_id' => 'strawberry', 'level' => 8],
['id' => 'bfrfnr', 'unique_id' => 'apple', 'level' => 4],
['id' => 'logujtng9', 'unique_id' => 'grapefruit', 'level' => 6],
['id' => '07yburhg', 'unique_id' => 'pinapple', 'level' => 1],
];
I need a way to remove the rows containing the same unique_id
value in both arrays so that I'm left with 2 arrays which only contain elements that do not exist in the other.
Desired results as two separate arrays:
[['id' => '434b5g6', 'unique_id' => 'banana', 'level' => 8]]
and
[['id' => '07yburhg', 'unique_id' => 'pinapple', 'level' => 1]]
I know there is array_diff()
, but this only works for single level arrays. I'm using multi-level arrays and only targeting the unique_id
column for comparisons.
Here a sample for PHP 5.3+:
$uniqueIds1 = array_map(function ($item) { return $item['unique_id']; }, $array1);
$uniqueIds2 = array_map(function ($item) { return $item['unique_id']; }, $array2);
$reallyUniqueIds = array_merge(array_diff($uniqueIds1, $uniqueIds2), array_diff($uniqueIds2, $uniqueIds1));
$filteredArray1 = array_filter($array1, function ($item) use ($reallyUniqueIds) {
return in_array($item['unique_id'], $reallyUniqueIds);
});
$filteredArray2 = array_filter($array2, function ($item) use ($reallyUniqueIds) {
return in_array($item['unique_id'], $reallyUniqueIds);
});
Explanation:
array_map(function ($item) { return $item['unique_id']; }, $array1)
This just extracts all unique_id
values into an array like array('banana', 'apple', ...)
.
array_merge(array_diff($uniqueIds1, $uniqueIds2), array_diff($uniqueIds2, $uniqueIds1));
This creates the diffs between the arrays both ways and merges them into one array, like:
array('banana', 'apple')
array('strawberry', 'apple')
-> array('banana', 'strawberry')
See array_diff
.
Then finally, this goes through the original arrays again to filter out all elements whose unique_key
is not in the array we created in the previous step:
array_filter($array1, function ($item) use ($reallyUniqueIds) {
return in_array($item['unique_id'], $reallyUniqueIds);
})
This just uses a custom callback function for array_filter
, which tells it to filter items where in_array($item['unique_id'], $reallyUniqueIds)
is false
.