You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中Collection的diff()返回空数组,预期有1个用户差异

问题分析与解决方案

我来帮你拆解这个问题:你想用Laravel集合的diff()方法找出两个集合中唯一的剩余用户,预期能得到1个结果,但实际返回了空数组。先看你的代码:

//110个用户
$brand_users = BrandUser::whereSegmentId($campaign->segment_id)
    ->orderBy('brand_user_id', 'ASC')
    ->get(['brand_user_id']);
//109个用户
$campaign_results = \App\CampaignResult::whereCampaignId($campaign_job->campaign_id)
    ->orderBy('brand_user_id', 'ASC')
    ->get(['brand_user_id']);
$diff = $brand_users->diff($campaign_results);

问题根源

Laravel Eloquent集合的diff()方法默认是对比整个模型实例,而不是你指定的brand_user_id字段。哪怕两个集合里的brand_user_id完全一致,但因为BrandUser和CampaignResult是不同的模型类,或者模型实例的其他隐藏属性(比如created_at)不同,都会被判定为不同的元素,导致diff()返回空数组。

解决办法

给你几个实用的方案,按需选择:

方案1:转成ID数组后对比

先把两个集合提取成纯brand_user_id的数组,再用数组或集合的差异方法:

// 提取ID数组
$brand_ids = $brand_users->pluck('brand_user_id')->toArray();
$result_ids = $campaign_results->pluck('brand_user_id')->toArray();

// 计算差异ID
$diff_ids = array_diff($brand_ids, $result_ids);

// 可选:转回BrandUser模型集合
$diff = BrandUser::whereIn('brand_user_id', $diff_ids)->get();

方案2:用diffUsing自定义对比规则

Laravel集合提供了diffUsing方法,让你自定义对比逻辑,只看brand_user_id:

$diff = $brand_users->diffUsing($campaign_results, function ($brandUser, $campaignResult) {
    // 用太空船运算符对比ID,相同返回0,不同返回非0
    return $brandUser->brand_user_id <=> $campaignResult->brand_user_id;
});

方案3:直接用查询构造器筛选

如果不需要先获取两个大集合,也可以直接用whereNotIn一步到位,效率更高:

$result_ids = $campaign_results->pluck('brand_user_id');
$diff = BrandUser::whereSegmentId($campaign->segment_id)
    ->whereNotIn('brand_user_id', $result_ids)
    ->get();

验证步骤

建议先打印两个集合的ID列表,确认确实存在一个差异,排除数据本身的问题:

dd($brand_users->pluck('brand_user_id'), $campaign_results->pluck('brand_user_id'));

内容的提问来源于stack exchange,提问作者dflow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:06:42