note 89635 modified in function.array-diff-assoc by thiago

From: Date: Thu, 30 Jul 2009 12:12:03 +0000
Subject: note 89635 modified in function.array-diff-assoc by thiago
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-158913@lists.php.net to get a copy of this message
I've worked on array_diff_assoc_recursive() mentioned by chinello at gmail dot com and I think it might be worth mentioning here. I wrote a dozen test cases and it seems to be holding up pretty well. <?php // dwarven Differences: // * Replaced isset() with array_key_exists() to account for keys with null contents // 55 dot php at imars dot com Differences: // Key differences: // * Removed redundant test; // * Returns false bool on exact match (not zero integer); // * Use type-precise comparison "!==" instead of loose "!="; // * Detect when $array2 contains extraneous elements; // * Returns "before" and "after" instead of only "before" arrays on mismatch. function array_compare($array1, $array2) { $diff = false; // Left-to-right foreach ($array1 as $key => $value) { if (!array_key_exists($key,$array2)) { $diff[0][$key] = $value; } elseif (is_array($value)) { if (!is_array($array2[$key])) { $diff[0][$key] = $value; $diff[1][$key] = $array2[$key]; } else { $new = array_compare($value, $array2[$key]); if ($new !== false) { if (isset($new[0])) $diff[0][$key] = $new[0]; if (isset($new[1])) $diff[1][$key] = $new[1]; }; }; } elseif ($array2[$key] !== $value) { $diff[0][$key] = $value; $diff[1][$key] = $array2[$key]; }; }; // Right-to-left foreach ($array2 as $key => $value) { if (!array_key_exists($key,$array1)) { $diff[1][$key] = $value; }; // No direct comparsion because matching keys were compared in the // left-to-right loop earlier, recursively. }; return $diff; }; ?> Note that to catch small type differences, you need to use var_dump() rather than print_r(). For example: <?php first = Array( 'first' => 'second', 'third' => 'fourth', 'fifth' => Array( 'oui' => 'yes', 'non' => 'no' ), 'sixth' => Array( 3, 4, 2, 1 ) ); $second = Array( 'first' => 'second', 'third' => 'fourth', 'fifth' => Array( 'oui' => 'yes', 'non' => 'no' ), 'sixth' => Array( 3, 4, '2', 1 ) ); $diff = array_compare($first, $second); if ($diff === false) echo "MATCH\n"; else var_dump($diff); ?> The above would immediately show that element "sixth", index 2, is int(2) in $first but string(1)"2" in $second. As per the original function, order for associative arrays does not matter, and of course it does with lists. [EDIT: Credits to php dot notes at dwarven dot co dot uk] --was-- I've worked on array_diff_assoc_recursive() mentioned by chinello at gmail dot com and I think it might be worth mentioning here. I wrote a dozen test cases and it seems to be holding up pretty well. <?php // Key differences: // * Removed redundant test; // * Returns false bool on exact match (not zero integer); // * Use type-precise comparison "!==" instead of loose "!="; // * Detect when $array2 contains extraneous elements; // * Returns "before" and "after" instead of only "before" arrays on mismatch. function array_compare($array1, $array2) { $diff = false; // Left-to-right foreach ($array1 as $key => $value) { if (!isset($array2[$key])) { $diff[0][$key] = $value; } elseif (is_array($value)) { if (!is_array($array2[$key])) { $diff[0][$key] = $value; $diff[1][$key] = $array2[$key]; } else { $new = array_compare($value, $array2[$key]); if ($new !== false) { if (isset($new[0])) $diff[0][$key] = $new[0]; if (isset($new[1])) $diff[1][$key] = $new[1]; }; }; } elseif ($array2[$key] !== $value) { $diff[0][$key] = $value; $diff[1][$key] = $array2[$key]; }; }; // Right-to-left foreach ($array2 as $key => $value) { if (!isset($array1[$key])) { $diff[1][$key] = $value; }; // No direct comparsion because matching keys were compared in the // left-to-right loop earlier, recursively. }; return $diff; }; ?> Note that to catch small type differences, you need to use var_dump() rather than print_r(). For example: <?php first = Array( 'first' => 'second', 'third' => 'fourth', 'fifth' => Array( 'oui' => 'yes', 'non' => 'no' ), 'sixth' => Array( 3, 4, 2, 1 ) ); $second = Array( 'first' => 'second', 'third' => 'fourth', 'fifth' => Array( 'oui' => 'yes', 'non' => 'no' ), 'sixth' => Array( 3, 4, '2', 1 ) ); $diff = array_compare($first, $second); if ($diff === false) echo "MATCH\n"; else var_dump($diff); ?> The above would immediately show that element "sixth", index 2, is int(2) in $first but string(1)"2" in $second. As per the original function, order for associative arrays does not matter, and of course it does with lists. http://php.net/manual/en/function.array-diff-assoc.php

« previous php.notes (#158913) next »