如何解决array_udiff的类型强制 [英] How to work around array_udiff's type coercion

查看:59
本文介绍了如何解决array_udiff的类型强制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将一个复杂对象数组与一个id数组进行比较,期望的结果是没有列出其id的任何对象的数组。

I want to compare an array of complex objects with an array of ids, with the expected result being an array of any object that did not have its id listed.

这听起来像是 array_udiff 的完美用例 ,但如果没有一些令人困惑的麻烦,我将无法使其正常运行。为了说明我对该函数的问题,下面是一个简化的示例:

This sounds like a perfect use case for array_udiff, but I couldn't get it work without some confusing hassle. To illustrate my problem with that function, here a boiled down example:

class Foo {
  public $id;
  public function __construct($id) {
    $this->id = $id;
  }
}

$foos = [new Foo(1), new Foo(2), new Foo(3), new Foo(4)];
$fooIds = [1, 2, 3, 4];

$diff = array_udiff($foos, $fooIds, function ($f, $i){ return $f->id - $i; });
print_r($diff);  // expected result: an empty array

// actual result:
// Array
// (
//     [1] => Foo Object
//         (
//             [id] => 2
//         )
// )
// Object of class Foo could not be converted to int :11

在我看来, array_udiff 次尝试在数组的元素之间进行某种类型的强制转换。我没有在文档中提及此问题,并且关于SO的一个问题似乎提出了类似的要求,但没有任何答案。我想知道的是:

It sounds to me like array_udiff tries to do some type coercion between the elements of the arrays. I found no mention of this in the docs, and one question on SO seems to ask something similar, but doesn't have any answers. What I'd like to know:


  • 为什么 array_udiff 的行为方式如此?如果我们可以提供任意的回调函数,则这种强制似乎是完全没有必要的,对我而言甚至是非常无益的。

  • 是否有解决此问题的好方法,或者我应该使用鉴于我的一般问题,功能是否有所不同?

  • Why does array_udiff behave this way? If we can supply an arbitrary callback function, this kind of coercion seems completely unnecessary, and in my case even very unhelpful.
  • Is there a good way to work around this, or should I use a different of function given my general problem?

推荐答案

虽然有点 ugly ,获得所需结果的看似最简单的方法是在比较之前进行类型检查。

Though a bit ugly, the seemingly simplest way to get the required result is to type-check before comparing.

<?php
declare(strict_types=1);

error_reporting(-1);
ini_set('display_errors', 'On');

class Foo
{
    public $id;

    public function __construct($id) {
        $this->id = $id;
    }
}

$foos = [new Foo(1), new Foo(2), new Foo(3), new Foo(4)];
$fooIds = [1, 2, 3, 4];

$diff = array_udiff($foos, $fooIds, function ($a, $b) {
    echo gettype($a), ' <=> ', gettype($b), "\n";

    if ($a instanceof Foo && $b instanceof Foo) {
        return $a->id <=> $b->id;
    }

    if ($a instanceof Foo) {
        return $a->id <=> $b;
    }

    if ($b instanceof Foo) {
        return $a <=> $b->id;
    }

    return $a <=> $b;
});

print_r($diff);  // expected result: an empty array

demo: https://3v4l.org/1uVYf

这篇关于如何解决array_udiff的类型强制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆