如何在Laravel中按children分组收藏?

How to group colllection by children in Laravel?

我有一个 collection 个“功能”,每个功能都有一个“功能组”。 1 个功能 belongsToMany 个功能组。

1 有 belongsToMany 辆汽车,所以它本身就是一个子collection。在我的汽车视图中,我想对功能进行分组。我该怎么做?

一个例子collection:

[
   {
      "id":1,
      "group_id":1,
      "name":"metallic",
      "pivot":{
         "car_id":1,
         "feature_id":1
      },
      "group":{
         "id":1,
         "name":"paint"
      }
   },
   {
      "id":2,
      "group_id":1,
      "name":"blue",
      "pivot":{
         "car_id":1,
         "feature_id":2
      },
      "group":{
         "id":1,
         "name":"paint"
      }
   },
   {
      "id":5,
      "group_id":2,
      "name":"gps",
      "pivot":{
         "car_id":1,
         "feature_id":5
      },
      "group":{
         "id":2,
         "name":"interior"
      }
   },
   {
      "id":6,
      "group_id":2,
      "name":"leather seats",
      "pivot":{
         "car_id":1,
         "feature_id":6
      },
      "group":{
         "id":2,
         "name":"interior"
      }
   }
]

想要的结果会是这样的:

[
   {
      "id":1,
      "name":"paint",
      "features":[
         {
            "id":1,
            "group_id":1,
            "name":"metallic"
         },
         {
            "id":2,
            "group_id":1,
            "name":"blue"
         }
      ]
   },
   {
      "id":2,
      "name":"interior",
      "features":[
         {
            "id":5,
            "group_id":2,
            "name":"gps"
         },
         {
            "id":6,
            "group_id":2,
            "name":"leather seats"
         }
      ]
   }
]

在我的 Controller 中,我正在尝试创建一个新的 collection,使用 each() 循环和 mergeRecursive(),如下所示:

$car = Car::where('slug', $slug)->first()->load('features.group');

$newCollection = collect(["group 1" => "feature 1"]);

$car->features->each(function ($item, $key) use($newCollection) {
    $current = collect([
        $item->group->name => $item->name,
    ]);
    $newCollection->mergeRecursive($current);
});

dd($newCollection);

return view('pages.car', [
    'car' => $car,
    'features' => $newCollection,
]);

我的 collection 中唯一的数据是我用来实例化它的虚拟数据。我错过了什么?

有什么指点吗?谢谢!

好的,我找到了解决方案。无需遍历集合即可创建新集合。有一个收集方法 groupBy() 可以解决这个问题:

$myCollection->groupBy('group_id');returns这个:

{
   "1":[
      {
         "id":1,
         "group_id":1,
         "name":"metallic",
         "pivot":{
            "car_id":1,
            "feature_id":1
         },
         "group":{
            "id":1,
            "name":"paint"
         }
      },
      {
         "id":2,
         "group_id":1,
         "name":"blue",
         "pivot":{
            "car_id":1,
            "feature_id":2
         },
         "group":{
            "id":1,
            "name":"paint"
         }
      }
   ],
   "2":[
      {
         "id":5,
         "group_id":2,
         "name":"gps",
         "pivot":{
            "car_id":1,
            "feature_id":5
         },
         "group":{
            "id":2,
            "name":"interior"
         }
      },
      {
         "id":6,
         "group_id":2,
         "name":"leather seats",
         "pivot":{
            "car_id":1,
            "feature_id":6
         },
         "group":{
            "id":2,
            "name":"interior"
         }
      }
   ]
}

或者我可以使用嵌套键,$myCollection->groupBy('group.name'); returns 这个:

{
   "paint":[
      {
         "id":1,
         "group_id":1,
         "name":"metallic",
         "pivot":{
            "car_id":1,
            "feature_id":1
         },
         "group":{
            "id":1,
            "name":"paint"
         }
      },
      {
         "id":2,
         "group_id":1,
         "name":"blue",
         "pivot":{
            "car_id":1,
            "feature_id":2
         },
         "group":{
            "id":1,
            "name":"paint"
         }
      }
   ],
   "interior":[
      {
         "id":5,
         "group_id":2,
         "name":"gps",
         "pivot":{
            "car_id":1,
            "feature_id":5
         },
         "group":{
            "id":2,
            "name":"interior"
         }
      },
      {
         "id":6,
         "group_id":2,
         "name":"leather seats",
         "pivot":{
            "car_id":1,
            "feature_id":6
         },
         "group":{
            "id":2,
            "name":"interior"
         }
      }
   ]
}

现在可以在 blade layout/component:

中使用 @foreach() 循环输出
@foreach ($features as $feature)
    <h3>{{ $feature[0]->group->name }}</h3>
    @foreach ($feature as $item)
        <div>{{ $item->name }}</div>
    @endforeach
@endforeach