【问题标题】:Get difference between two multidimensional arrays by comparing rows [duplicate]在 PHP 中使用 array_diff_assoc 函数
【发布时间】:2011-08-29 05:37:35
【问题描述】:

您好,我有两个嵌套数组,需要找出引用数组和数据数组之间的差异。我正在使用 array_dif_assoc 函数,并且无法获得正确的差异,我不确定为什么我无法获得它。如果我犯了一些错误或者我必须递归地做,有人可以帮助我吗?

$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));

我得到一个空数组。当我使用 array_diff_assoc 时,我应该得到带有 course2 和 course3 的数组,因为它们不是第二个数组的一部分。

我错过了 PHP 端的一些逻辑吗??

【问题讨论】:

    标签: php arrays multidimensional-array associative-array


    【解决方案1】:

    您总是可以从阅读 PHP 手册开始。

    对于array_diff_assoc(在http://php.net/manual/en/function.array-diff-assoc.php)据说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]);.

    在用户 cmets 中提供的解决方案(这确实有效):

    imas dot com 的 55 dot php 2009 年 3 月 17 日 03:09 我工作过 array_diff_assoc_recursive() 提到 通过 chinello 在 gmail dot com 和我 认为这可能值得一提 这里。我写了十几个测试用例 它似乎保持得很好。

    <?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;
    };
    ?>
    

    【讨论】:

    • 你必须将 diff 初始化重构为 $diff = array(),因为我认为只返回 array|bool 而不是 array() 的函数不是好的解决方案。
    【解决方案2】:

    您不应使用_assoc,而应使用普通的array_diffarray_intersect,否则它将比较外部数组的顺序而不仅仅是内容。

    array_diff 也不适用于子数组,您需要一种解决方法:

    print_r(
      array_map("unserialize",
        array_diff(
          array_map("serialize", $allCoursesAvailable),
          array_map("serialize", $allCoursesforUser)
        )
      )
    );
    

    这会给你:

    [2] => Array
        (
            [id] => 1
            [name] => course2
        )
    
    [3] => Array
        (
            [id] => 3
            [name] => course3
        )
    

    不确定这是否是您想要的。手动操作可能仍然是可取的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-05
      • 1970-01-01
      • 1970-01-01
      • 2013-03-11
      • 2012-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多