Last active
July 10, 2018 07:43
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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]; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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