开发者

Get difference between two multidimensional arrays by comparing rows [duplicate]

This question already has answers here: While comparing associative rows between开发者_StackOverflow two 2d arrays, array_diff_assoc() gives the wrong difference (3 answers) Get difference between associative rows of two 2-dimensional arrays (5 answers) Closed last year.

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜