合并2个收藏(保留相似的收藏)

时间:2019-05-29 09:32:07

标签: laravel

我有几个集合,我只想保留每个集合中存在的元素。

我尝试了可用的方法,但是没有找到任何匹配的方法。

$candidatesByConsultant = Consultant::find(request('consultant_id'))->candidates;
$candidatesByCreation = Candidate::whereBetween('created_at',[Carbon::parse(request('meeting_since')), Carbon::parse(request('meeting_to'))])->get();

你有什么主意吗? :)

3 个答案:

答案 0 :(得分:1)

要使值仅出现在两个集合中,必须使用相交方法:

$result = $candidatesByConsultant->intersect($candidatesByCreation);

相交方法使两个集合的值相交。您可以在Laravel的官方documentation中阅读它。

为了获得两个集合都不存在的结果,必须使用diff方法:

$result = $candidatesByConsultant->diff($candidatesByCreation);

diff方法查找集合之间的差异。您可以在Laravel的官方documentation中阅读它。

答案 1 :(得分:0)

intersect方法可能合适:https://laravel.com/docs/5.8/collections#method-intersect

示例摘自文档:

$collection = collect(['Desk', 'Sofa', 'Chair']);

$intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']);

$intersect->all();

// [0 => 'Desk', 2 => 'Chair']

但是,特别是如果您要与口才模型的多个集合相交时,由于两个模型之间的相等性是由Model :: is()方法定义的,因此它可能无法工作。校验 https://laravel.com/docs/5.8/eloquent#comparing-models了解有关比较两种口才模型的更多信息。

要处理此问题,我将执行以下操作,假设您模型的主键为id

$candidatesByConsultant = Consultant::find(request('consultant_id'))->candidates;
$candidatesByCreation = Candidate::whereBetween('created_at',[Carbon::parse(request('meeting_since')), Carbon::parse(request('meeting_to'))])->get();

$candidates = $candidatesByConsultant->merge($candidatesByCreation)->unique("id");

您可以查看merge()unique()文档。

答案 2 :(得分:0)

内置$collection->intersect($other),但您也可以使用简单的自定义过滤器获得所需的结果:

$left  = collect([Model::find(1), Model::find(2), Model::find(3)]);
$right = collect([Model::find(1), Model::find(3), Model::find(5)]);

$result = $left->filter(function ($value, $key) use ($right) {
    return $right->contains(function ($v, $k) use ($value) {
        return $v->id === $value->id;
    });
});

这将通过id执行模型比较。它不是很出色。另一种方法是检索两个ids数组,将它们相交并根据此列表过滤合并的集合:

$left   = collect([Model::find(1), Model::find(2), Model::find(3)]);
$right  = collect([Model::find(1), Model::find(3), Model::find(5)]);
$merged = $left->merge($right);

$ids = array_intersect($left->pluck('id')->toArray(), $right->pluck('id')->toArray());

$result = $merged->filter(function ($value, $key) use ($ids) {
    return in_array($value->id, $ids);
});