douyou2368
2011-05-19 21:26 浏览 21
已采纳

在PHP中使用array_diff_assoc函数

Hello 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??

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

3条回答 默认 最新

  • 已采纳
    dongnaigu2052 dongnaigu2052 2011-05-19 21:44

    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;
    };
    ?>
    
    点赞 评论 复制链接分享
  • dongyi7041 dongyi7041 2011-05-19 21:36

    I think the built in array diffs are shallow, meaning they only check the first level and wont look through the arrays inside of it.

    Some solutions here:

    PHP - Mutidimensional array diff

    点赞 评论 复制链接分享
  • doushui20090526 doushui20090526 2011-05-19 21:42

    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.

    点赞 评论 复制链接分享

相关推荐