php - 为什么array_unique不检测重复的对象?

标签 php

我似乎无法弄清楚PHP幕后正在发生什么魔术,为什么array_unique无法检测到我的重复数据。

在我的特定情况下,我有2个用户集合,我将这些集合合并为一个集合,然后仅保留唯一的条目。为此,我将两个集合都转换为数组,对其进行array_merge()编码,然后根据参数应用array_unique(..., SORT_REGULAR),以便将它们作为对象进行比较,而无需进行任何转换。我意识到比较对象是一个滑坡,但是在这种情况下,它比我要怪。

合并之后但在唯一性检查之前,我有以下状态:
enter image description here

如您所见,项目4和11是相同的用户实体(非严格和严格比较都同意这一点)。但是在array_unique()之后,由于某种原因,它们都保留在列表中:
enter image description here

如您所见,检测到并删除了项目7-10,但没有检测到项目11。

那怎么可能?我在这里没看到什么?

当前正在运行PHP 7.4.5

代码来自使用Symfony 4.4.7和Doctrine ORM 2.7.2的项目(尽管我认为这应该无关紧要,如果=====比较对象相等)。

奖励积分的有趣事实-连续两次应用array_unique会产生实际上唯一的结果:
enter image description here

头脑=吹牛

更新:我已在throw new \RuntimeException()方法中添加了User::__toString(),以确保没有人进行字符串转换。

请不要建议转换为字符串-这既不是我的问题的解决方案,也不是这个问题的内容。

最佳答案

对于您眼前的问题,我真的怀疑这是由于
使用array_unique标志时,SORT_REGULAR通过以下方法从数组中删除元素:

  • sorting it
  • removing adjacent items if they are equal

  • 并且因为您在Proxy集合的中间确实有一个User对象,所以这可能会导致您当前面临的问题。

    正如 sort page of PHP documentation指出的那样,这似乎得到Marvin's comment警告的支持。

    Warning Be careful when sorting arrays with mixed types values because sort() can produce unexpected results, if sort_flags is SORT_REGULAR.



    资料来源:https://www.php.net/manual/en/function.sort.php#refsect1-function.sort-notes

    现在为可能的解决方案,这可能会给您带来一些Symfony的味道。

    它使用ArrayCollection filter contains 方法来过滤第二个集合,并仅添加第一个集合中不存在的元素。
    为了完全完成,此解决方案还利用了 use language construct,以便将第二个ArrayCollection传递给filter所需的闭包函数。

    这将导致一个不包含重复用户的新ArrayCollection

    public static function merge(Collection $a, Collection $b, bool $unique = false): Collection {
      if($unique){
        return new ArrayCollection(
          array_merge(
            $a->toArray(),
            $b->filter(function($item) use ($a){
              return !$a->contains($item);
            })->toArray()
          )
        );
      }
    
      return new ArrayCollection(array_merge($a->toArray(), $b->toArray()));
    }
    

    关于php - 为什么array_unique不检测重复的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61910894/

    相关文章:

    php - 在 PHP/MySQL 中只获取一行

    PHP MySQL 使用条件连接连接两个表

    php - mysql加入: get all rows that matches the rows that matches notification type is zero

    php - 在 php 的 stackoverflow 上有像这里这样的成就系统吗?

    php - MediaWiki 1.20.0 中如何通过大小写用户名搜索用户贡献?

    c# - 如何使用 SOAP V2 为 Magento 设置自定义 api?

    Javascript true 条件未执行

    php - Doctrine 2.0 是否像 Propel 1.5 那样预先生成模型类?

    php - 有没有办法用 yii\rbac\PhpManager 刷新 Yii2 中缓存的 rbac 项?

    PHP 缩略图按比例调整大小