Get difference between two multidimensional arrays by comparing rows [duplicate]
I have two nested arrays and need to find the difference between the reference array and the data array. I am using array_dif_assoc function, and am unable to get the right difference, I am not sure why I am unable to get it. Could somebody help me out if I am doing some mistake or if I have to do it recursively;
$allCoursesAvailable = array(array('id'=>0,'name'=>'Select-One'), array('id'=>1,'name'=>'course1'),array('id'=>1,'name'=>'course2'),array('id'=>3,'name'=>'course3'));
$allCoursesforUser = array(array('id'=>0,'name'=>'Select-One'), array('id'=>1,'name'=>'course1'),array('id'=>4,'name'=>'course4'),array('id'=>5,'name'=>'course5'),array('id'=>6,'name'=>'course4'));
echo '<pre>';print_r(array_diff_assoc($allCoursesAvailable,$allCoursesforUser));
I am getting an empty array with this. When I use array_diff_assoc()
, I should have got the arrays carrying course2 and course3, as they are not part of the 2nd array.
Am I missing some logic on the PHP end?
You could always start by reading the PHP manual.
For array_diff_assoc
(on http://php.net/manual/en/function.array-diff-assoc.php) it is said that this function only checks one dimension of a n-dimensional array. Of course you can check deeper dimensions by using, for example, array_diff_assoc($array1[0], $array2[0]);.
Provided solution in user comments (this does work):
55 dot php at imars dot com 17-Mar-2009 03:09 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;
};
?>
You should not use _assoc
but the normal array_diff
or array_intersect
, because otherwise it will compare the ordering of the outer array and not just the content.
Also array_diff doesn't really work with subarrays, and you'd need a workaround:
print_r(
array_map("unserialize",
array_diff(
array_map("serialize", $allCoursesAvailable),
array_map("serialize", $allCoursesforUser)
)
)
);
Which would give you:
[2] => Array
(
[id] => 1
[name] => course2
)
[3] => Array
(
[id] => 3
[name] => course3
)
Not sure if that is what you wanted. And doing it manually might be advisable still.
精彩评论