Skip to content

Instantly share code, notes, and snippets.

@Finesse
Last active July 10, 2018 07:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Finesse/d2e6aa55461898c7339c857f4fe6be8b to your computer and use it in GitHub Desktop.
Save Finesse/d2e6aa55461898c7339c857f4fe6be8b to your computer and use it in GitHub Desktop.
A PHP function to find a difference between 2 arrays. Can use a custom compare logic.
<?php
/**
* Compares 2 arrays. Detects what needs to be removed from and added to the first array to turn it to the second array.
*
* @param array $array1
* @param array $array2
* @param callable|null $areEqual Detects whether two array elements are equal. The first argument is a first array
* value, the second argument is a second array value.
* @return array[] An array with keys:
* - 0 - First array values that are not presented in the second array;
* - 1 - Second array values that are not presented in the first array;
* - 2 - Values presented in both arrays. Each array value is an array containing two values: a value from the first
* array and the corresponding value from the second array.
*/
function getArraysDifference(array $array1, array $array2, callable $areEqual = null): array
{
$areEqual = $areEqual ?? function ($v1, $v2) { return $v1 === $v2; };
$in1Only = [];
$inBoth = [];
foreach ($array1 as $value1) {
// Looking for the array1 value in array2
foreach ($array2 as $index2 => $value2) {
if ($areEqual($value1, $value2)) {
// If it is found, adding it to the "both" list
$inBoth[] = [$value1, $value2];
unset($array2[$index2]);
continue 2;
}
}
// If it is not found, adding it to the "only in array1" list
$in1Only[] = $value1;
}
// Adding the rest values from array2 to the "only in array2" list
$in2Only = array_values($array2);
return [$in1Only, $in2Only, $inBoth];
}
<?php
// Requires PHPUnit
$this->assertEquals(
[['bar'], ['qoo'], [['foo', 'foo'], ['baz', 'baz']]],
getArraysDifference(['foo', 'bar', 'baz'], ['baz', 'qoo', 'foo'])
);
$this->assertEquals([
[11, 245],
[29, 91, 3],
[[56, 55], [43, 41]]
], getArraysDifference(
[56, 43, 11, 245],
[41, 29, 91, 55, 3],
function ($a, $b) { return floor($a / 10) == floor($b / 10); }
));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment