代码之家  ›  专栏  ›  技术社区  ›  senty

雄辩的集合包含()工作,但diff()或intersect()认为所有内容都不同

  •  0
  • senty  · 技术社区  · 5 年前

    我有一组字符串可以帮助我启动和 find() 相关模型。

    $arr = [
       "App\Post"  => 1,
       "App\Video" => 1
    ];
    // this array is [Model => ModelId]
    

    此时,我将从字符串启动模型类并使用 查找() 找到模型对象。

    我也有两种关系 morphByMany() 在我的用户模型中,它将返回这两者的集合。

    // class User
    public function entities() {
      // this returns merged collection successfully
      return ($this->videos)->merge($this->posts);
    }
    

    在这一点上,如果我尝试 contains() , 它起作用了 :

    foreach ($arr as $modelString => $modelId) {
         // this finds the related model:
         $model = $modelString::find($modelId)->first(); 
    
         $this->entities()->contains($model); // returns true
    }
    

    但是,如果我尝试基于我的初始模型创建一个新的集合, $collection->diff($collection2) $collection->intersect($collection) 不起作用 .

    $collection1 = $this->entities();
    $collection2 = collect();
    
    foreach ($arr as $modelString => $modelId) {
         $model = $modelString::find($modelId)->first(); 
    
         $collection2->push($model);
    }
    
    $collection1->diff($collection2); // returns all items
    $collection1->intersect($collection2); // returns []
    
    // intersect() and diff() should be other way around
    

    (只是为了澄清,两个 $this->entities() $arr 有相同的型号。唯一的区别是 $this->实体() 与模型一起返回轴值,而从 阿尔 没有;但是 包含() 工作。

    0 回复  |  直到 5 年前
        1
  •  0
  •   Chin Leung    5 年前

    我在最新版本的Laravel上测试过这个,我不能复制你提到的部分 ->contains 退货 true . 我得到 false 当我尝试 contains 正如您所做的,这是预期的行为,因为一个有关系的模型和另一个没有关系的模型被认为是不同的。

    你可以使用这个函数 diffUsing 通过回调来检查类和项的ID是否相同。

    $c1->diffUsing($c2, function ($a, $b) {
        return get_class($a) != get_class($b) || $a->id != $b->id;
    });
    
        2
  •  0
  •   senty    5 年前

    @梁振英的“一个有关系的模型和另一个没有关系的模型被认为是不同的”,给了我一种不同的思考方式。

    $collection1 = $this->entities()->map(function($item) {
        return $item->unsetRelation('pivot');
    });
    

    然后, diff() intersect() 按预期开始工作!