通过比较特定列/属性中的值来获取两个对象数组的差异

问题描述 投票:0回答:5

我知道有

array_diff
array_udiff
用于比较两个数组之间的差异,但是我该如何处理两个对象数组呢?

array(4) {
    [0]=>
        object(stdClass)#32 (9) {
            ["id"]=>
            string(3) "205"
            ["day_id"]=>
            string(2) "12"
        }
}

我的数组就像这个,我有兴趣根据

id
列值查看两个数组的差异。

php arrays object filtering array-difference
5个回答
88
投票

这正是

array_udiff
的用途。编写一个按照您想要的方式比较两个对象的函数,然后告诉
array_udiff
使用该函数。像这样的东西:

function compare_objects($obj_a, $obj_b) {
  return $obj_a->id - $obj_b->id;
}

$diff = array_udiff($first_array, $second_array, 'compare_objects');

或者,如果您使用 PHP >= 5.3,您可以只使用 匿名函数 而不是声明函数:

$diff = array_udiff($first_array, $second_array,
  function ($obj_a, $obj_b) {
    return $obj_a->id - $obj_b->id;
  }
);

7
投票

如果您想根据对象实例运行差异,还有另一个选择。您可以使用它作为对

array_udiff
:

的回调
function compare_objects($a, $b) {
    return strcmp(spl_object_hash($a), spl_object_hash($b));
}

只有在确定数组都只包含对象时才需要使用它 - 这是我个人的用例


7
投票

如果您想比较字符串属性(例如名称),这里是另一个选择:

$diff = array_udiff($first_array, $second_array,
  function ($obj_a, $obj_b) {
    return strcmp($obj_a->name, $obj_b->name);
  }
);

0
投票

这是我对此的看法

/**
     * Compare two objects (active record models) and return the difference. It wil skip ID from both objects as 
     * it will be obviously different
     * Note: make sure that the attributes of the first object are present in the second object, otherwise
     * this routine will give exception.
     * 
     * @param object $object1
     * @param object $object2
     * 
     * @return array difference array in key-value pair, empty array if there is no difference
     */
    public static function compareTwoObjects($object1, $object2)
    {
        $differences=[];
        foreach($object1->attributes as $key => $value) {
            if($key =='id'){
                continue;
            }
            if($object1->$key != $object2->$key){
                $differences[$key] = array(
                                            'old' => $object1->$key,
                                            'new' => $object2->$key
                                        );
            }
        }
        return $differences;
    }

0
投票

您有两个包含对象的数组 - 使用

array_udiff()
当然适合此任务。

我将用现代语法(“宇宙飞船运算符”和“箭头函数语法”)演示这项技术。

考虑这个示例数据集:

$array1 = [
    (object) ['id' => '204', 'day_id' => '12'],
    (object) ['id' => '205', 'day_id' => '13'],
    (object) ['id' => '206', 'day_id' => '14'],
    (object) ['id' => '207', 'day_id' => '15'],
];
$array2 = [
    (object) ['id' => '203', 'day_id' => '11'],
    (object) ['id' => '205', 'day_id' => '13'],
    (object) ['id' => '207', 'day_id' => '14'],
    (object) ['id' => '209', 'day_id' => '17'],
];

array_udiff()
返回的数据将是第一个数组中与第二个数组中不匹配的行。

代码:(演示

var_export(
    array_udiff(
        $array1,
        $array2,
        fn($a, $b) => $a->id <=> $b->id
    )
);

返回这两行:

[
    (object) ['id' => '204', 'day_id' => '12'],
    (object) ['id' => '206', 'day_id' => '14'],
]

颠倒前两个参数的顺序:(Demo)

[
    (object) ['id' => '203', 'day_id' => '11'],
    (object) ['id' => '209', 'day_id' => '17'],
)
© www.soinside.com 2019 - 2024. All rights reserved.