通过特定的对象键值比较两个对象数组

时间:2018-10-17 15:04:44

标签: php

这可能真的很简单,但我似乎无法理解。我有对象$a$b的两个数组。在$a中,我有带有键email的对象,在$b中,我有带有user_email的对象(由于来自API,因此无法更改)。我想要输出包含所有对象$c的第三个数组email == user_email。我尝试像这样使用array_udiff

$c = array_udiff($a, $b,
    function ($obj_a, $obj_b) {
        return $obj_a->email - $obj_b->user_email;
    }
);

由于某种原因,$ obj_b并不总是像我想的那样来自数组$b的对象。有没有干净的解决方案?谢谢。

1 个答案:

答案 0 :(得分:1)

您可能正在寻找array_uintersect。另外,您应该将字符串与strcmp进行比较,甚至与strcasecmp进行比较。请记住,PHP将数组元素传递给回调的顺序并不总是与数组的顺序相同。

$a = [(object)['email' => 'a'], (object)['email' => 'b'], (object)['email' => 'c']];
$b = [(object)['user_email' => 'c'], (object)['user_email' => 'a'], (object)['user_email' => 'd']];

$comparer = function($obj_a, $obj_b) {
    $email_a = property_exists($obj_a, 'email')
        ? $obj_a->email
        : $obj_a->user_email;

    $email_b = property_exists($obj_b, 'email')
        ? $obj_b->email
        : $obj_b->user_email;

    return strcasecmp($email_a, $email_b);
};

// only objects with email property
$c = array_uintersect($a, $b, $comparer);

// both objects with email and user_email property
$d = array_merge(
    array_uintersect($a, $b, $comparer),
    array_uintersect($b, $a, $comparer)
);

如果参数是具体类,则可以将使用property_exists进行测试更改为使用instanceof进行测试。