合并2个集合(保留相似的)

问题描述 投票:0回答:3

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

我检查了可用的方法,但没有找到任何匹配的方法。

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

你有什么想法吗? :)

php laravel collections intersection
3个回答
1
投票

为了获得仅出现在两个集合中的值,您必须使用 intersect 方法:

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

intersect 方法将两个集合的值相交。你可以在 Laravel 的官方文档中阅读。

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

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

diff 方法查找集合之间的差异。你可以在 Laravel 的官方文档中阅读。


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']

但是,特别是如果您尝试交叉多个 Eloquent 模型 集合,它可能不起作用,因为两个模型之间的相等性是由 Model::is() 方法定义的。查看 https://laravel.com/docs/5.8/eloquent#comparing-models 有关比较两个 Eloquent 模型的更多信息。

为了处理这个问题,我会执行以下操作,假设模型的主键是

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() 文档。


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);
});
© www.soinside.com 2019 - 2024. All rights reserved.