如何在Laravel集合中仅对部分元素进行分组?
如何在Laravel集合中仅对部分元素进行分组?
嘿,我来帮你搞定这个问题!先看看你的数据:你有厂商表(manufacturers)和车型表(makes),其中有些车型和所属厂商同名(比如Honda厂商对应Honda车型),有些是厂商的子品牌(比如Honda的Acura)。你想要的应该是只对子品牌进行分组,把它们归到对应的厂商下,同时保留那些和厂商同名的车型作为顶级条目,对吧?
我给你两种实用的实现方式,你可以根据自己的需求来选:
方式一:先拆分再合并,逻辑更直观
首先我们从数据库获取关联好的车型数据:
// 先获取所有车型,并预加载对应的厂商关联 $makes = Make::with('manufacturer')->get();
接下来把集合拆成两部分:和厂商同名的「主车型」,以及子品牌车型:
// 筛选出与所属厂商同名的主车型 $mainMakes = $makes->filter(fn($make) => $make->name === $make->manufacturer->name); // 筛选出子品牌,并且直接按厂商名称分组 $groupedSubMakes = $makes->filter(fn($make) => $make->name !== $make->manufacturer->name) ->groupBy(fn($make) => $make->manufacturer->name);
然后把这两部分合并成我们想要的结构——把每个厂商的子品牌挂到对应的主车型下面:
$finalResult = collect(); $mainMakes->each(function ($mainMake) use ($groupedSubMakes, $finalResult) { $finalResult->push([ 'manufacturer_name' => $mainMake->manufacturer->name, 'main_model' => $mainMake->name, 'sub_brands' => $groupedSubMakes->get($mainMake->name, collect()) ]); });
这样处理后,$finalResult的结构就会是每个厂商对应一个条目,里面包含主车型和它的子品牌列表,完全符合你的需求。
方式二:自定义分组键,一步到位
如果你想更简洁一点,可以直接在分组的时候自定义键,然后再整理结构:
$makes = Make::with('manufacturer')->get(); $grouped = $makes->groupBy(function ($make) { // 核心逻辑:主用车的分组键用自己的名称,子品牌用所属厂商的名称 return $make->name === $make->manufacturer->name ? $make->name : $make->manufacturer->name; })->map(function ($group, $key) { // 每个分组里,把主车型和子品牌分开 return [ 'main_model' => $group->firstWhere('name', $key), 'sub_brands' => $group->filter(fn($make) => $make->name !== $key) ]; });
这种方式的好处是代码更紧凑,所有逻辑在一个链式操作里完成,最终的$grouped集合就是按厂商/主车型分组好的结构,子品牌都归到了对应的组里。
不管用哪种方式,核心都是先区分需要分组的元素(子品牌)和不需要分组的元素(主车型),然后用Laravel集合的filter、groupBy这些方法组合实现你的需求。你可以根据自己项目的代码风格来选择~
备注:内容来源于stack exchange,提问作者miken32
相关产品推荐
相关产品推荐

