Skip to content

Instantly share code, notes, and snippets.

@cjthompson
Last active April 7, 2024 00:30
Show Gist options
  • Star 24 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save cjthompson/5485005 to your computer and use it in GitHub Desktop.
Save cjthompson/5485005 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).
<?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);
}
<?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);
}
}
@gzc07
Copy link

gzc07 commented May 11, 2018

good

@lexkyiv
Copy link

lexkyiv commented Apr 7, 2024

good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment