合并分组 Laravel 集合中的重复项和 return 特定字段的总和

Merge duplicates in a grouped Laravel Collection and return a sum of a specific field


我正在为客户制作一个应用程序,用户可以在其中输入已售出圣诞树的规格,并以 JSON 格式存储在数据库中,如 "line_items"。它需要在送货单上的 table 中输出,以供客户查看。用户有这样的情况,其中多个托盘装载到一辆卡车上,卡车上装有相同大小的相同树种。在那种情况下,我想合并重复项并求和。

我想到了这个:

$data = collect($deliveryNote->line_items)
->groupBy(['type', 'size']);

这给了我下面的输出。

{
"NGR": {
 "125-150": [
  {
   "slot": 2,
   "pallet": "cghjh",
   "type": "NGR",
   "label": "purple",
   "size": "125-150",
   "amount": "30"
  },
  {
   "slot": 3,
   "pallet": "cghjh",
   "type": "NGR",
   "label": "purple",
   "size": "125-150",
   "amount": "30"
  }
 ],
 "150-175": [
  {
   "slot": 2,
   "pallet": "yghiuj",
   "type": "NGR",
   "label": "orange",
   "size": "150-175",
   "amount": "30"
  }
 ]
 },
"NOB": {
 "125-150": [
  {
   "slot": 3,
   "pallet": "cghjh",
   "type": "NOB",
   "label": "purple",
   "size": "125-150",
   "amount": "30"
  }
 ]
 }
}

这几乎是我想要的分组方式。 现在我想合并重复项,过滤掉“slot”、“pallet”、“label”并更新集合的数量以显示如下:

{
"NGR": {
 "125-150": [
  {
   "type": "NGR",
   "size": "125-150",
   "amount": "60"
  },
 ],
 "150-175": [
  {
   "type": "NGR",
   "size": "150-175",
   "amount": "30"
  }
 ]
 },
"NOB": {
 "125-150": [
  {
   "type": "NOB",
   "size": "125-150",
   "amount": "30"
  }
 ]
 }
}

我试过这个:

$data = collect($deliveryNote->line_items)
->groupBy(['type', 'size']);
->map(function ($item) {
   return $item->sum('amount');
});

它没有给我正确的输出。

我希望任何人有时间帮助我。 提前谢谢你。

在你的最后一个例子中,你只是迭代“NGR”、“NOB”键和因此值,为了得到你想要求和的树,你必须在你的迭代中更深一层。

很难确定 line_items 是关系还是自定义数据集,假设写在评论中。

$data = collect($deliveryNote->line_items)
    ->groupBy(['type', 'size']);
    ->map(function ($tree) {
        // i assume $trees is an array else don't wrap
        return collect($trees)->map(function ($shipments) {
            return [
                'amount' => $shipments->sum('amount'),
                // assuming object, if array access it like so
                'size' => $shipments->first()->size,
                'amount' => $shipments->first()->amount,
            ];
        });
    });