-
-
Save minhphuc429/1efd1cb0a3ae86100e6cd73a3099747f to your computer and use it in GitHub Desktop.
PHP: Compare two arrays and find the differences between them. Supports items that are arrays by serializing them for comparison. Returns an array of insertions (only in the second array) and deletions (only in the first array).
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 | |
/** | |
* Compare two arrays and return a list of items only in array1 (deletions) and only in array2 (insertions) | |
* | |
* @param array $array1 The 'original' array, for comparison. Items that exist here only are considered to be deleted (deletions). | |
* @param array $array2 The 'new' array. Items that exist here only are considered to be new items (insertions). | |
* @param array $keysToCompare A list of array key names that should be used for comparison of arrays (ignore all other keys) | |
* @return array[] array with keys 'insertions' and 'deletions' | |
*/ | |
public static function arrayDifference(array $array1, array $array2, array $keysToCompare = null) { | |
$serialize = function (&$item, $idx, $keysToCompare) { | |
if (is_array($item) && $keysToCompare) { | |
$a = array(); | |
foreach ($keysToCompare as $k) { | |
if (array_key_exists($k, $item)) { | |
$a[$k] = $item[$k]; | |
} | |
} | |
$item = $a; | |
} | |
$item = serialize($item); | |
}; | |
$deserialize = function (&$item) { | |
$item = unserialize($item); | |
}; | |
array_walk($array1, $serialize, $keysToCompare); | |
array_walk($array2, $serialize, $keysToCompare); | |
// Items that are in the original array but not the new one | |
$deletions = array_diff($array1, $array2); | |
$insertions = array_diff($array2, $array1); | |
array_walk($insertions, $deserialize); | |
array_walk($deletions, $deserialize); | |
return array('insertions' => $insertions, 'deletions' => $deletions); | |
} |
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 | |
class arrayDifferenceTest extends PHPUnit_Framework_TestCase { | |
public function testArrayDifference() { | |
$a1 = array( | |
array('id' => 1, 'eventid' => 2, 'calid' => 3, 'type' => 'A'), | |
array('id' => 2, 'eventid' => 2, 'calid' => 4, 'type' => 'B'), // index 1 is the deleted element | |
array('id' => 3, 'eventid' => 2, 'calid' => 5, 'type' => 'A') | |
); | |
$a2 = array( | |
array('id' => 1, 'eventid' => 2, 'calid' => 3, 'type' => 'A'), | |
array('id' => 3, 'eventid' => 2, 'calid' => 5, 'type' => 'A'), | |
array('id' => 4, 'eventid' => 2, 'calid' => 6, 'type' => 'B') // index 2 is the inserted element | |
); | |
$diff = arrayDifference($a1, $a2); | |
$this->assertSame(array( | |
'insertions' => array( | |
2 => array( | |
'id' => 4, | |
'eventid' => 2, | |
'calid' => 6, | |
'type' => 'B', | |
), | |
), | |
'deletions' => array( | |
1 => array( | |
'id' => 2, | |
'eventid' => 2, | |
'calid' => 4, | |
'type' => 'B', | |
), | |
), | |
), $diff); | |
} | |
public function testArrayDifferenceSimple() { | |
$a1 = array(1, 2, | |
array('id' => 3, 'eventid' => 2, 'calid' => 5, 'type' => 'A'), | |
array('id' => 4, 'eventid' => 2, 'calid' => 5, 'type' => 'A'), | |
'3' | |
); | |
$a2 = array(1, | |
array('id' => 3, 'eventid' => 2, 'calid' => 5, 'type' => 'A'), | |
array('id' => 5, 'eventid' => 2, 'calid' => 5, 'type' => 'A'), | |
'3', | |
4 | |
); | |
$diff = arrayDifference($a1, $a2); | |
$this->assertSame(array ( | |
'insertions' => array( | |
2 => array ( | |
'id' => 5, | |
'eventid' => 2, | |
'calid' => 5, | |
'type' => 'A', | |
), | |
4 => 4, | |
), | |
'deletions' => array( | |
1 => 2, | |
3 => array ( | |
'id' => 4, | |
'eventid' => 2, | |
'calid' => 5, | |
'type' => 'A', | |
), | |
), | |
), $diff); | |
} | |
public function testArrayDifferenceWithIgnore() { | |
$a1 = array( | |
array('id' => 1, 'eventid' => 2, 'calid' => 3, 'type' => 'A'), | |
array('id' => 2, 'eventid' => 2, 'calid' => 4, 'type' => 'B'), // index 1 is the deleted element | |
array('id' => 3, 'eventid' => 2, 'calid' => 5, 'type' => 'A') | |
); | |
$a2 = array( | |
array('id' => 1, 'eventid' => 2, 'calid' => 3, 'type' => 'A'), | |
array('id' => 3, 'eventid' => 2, 'calid' => 5, 'type' => 'A'), | |
array('id' => 4, 'eventid' => 2, 'calid' => 6, 'type' => 'B') // index 2 is the inserted element | |
); | |
$diff = arrayDifference($a1, $a2, array('calid')); | |
$this->assertSame(array( | |
'insertions' => array( | |
2 => array( | |
'calid' => 6, | |
), | |
), | |
'deletions' => array( | |
1 => array( | |
'calid' => 4, | |
), | |
), | |
), $diff); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment