skip to Main Content

I have this collection:

$stocks = collect(
    [
        ['sku' => '123', 'batch' => '123', 'qty_total' => 1],
        ['sku' => '1233', 'batch' => '123', 'qty_total' => 2],
        ['sku' => '123', 'batch' => '123', 'qty_total' => 3],
        ['sku' => '5', 'batch' => '123', 'qty_total' => 4],
    ]
);

And I need get in output collection like this:

[
        ['sku' => '123', 'batch' => '123', 'qty_total' => 4],
        ['sku' => '1233', 'batch' => '123', 'qty_total' => 2],
        ['sku' => '5', 'batch' => '123', 'qty_total' => 4],
    ]

I’m grouping collection with

$coll = $coll
    ->groupBy(['sku','batch'], true)

But I don’t understand how I must sum next.

2

Answers


  1. You can do it like this :

      $stocks = collect(
       [
          ['sku' => '123', 'batch' => '123', 'qty_total' => 1],
          ['sku' => '1233', 'batch' => '123', 'qty_total' => 2],
          ['sku' => '123', 'batch' => '123', 'qty_total' => 3],
          ['sku' => '5', 'batch' => '123', 'qty_total' => 4],
       ]
      );
    
    return $stocks->groupBy(['sku','batch'], true)->map(function($items){
      $firstItem = $items->values()->first();
    
      return collect($firstItem->first())->merge([
        'qty_total' => $firstItem->sum('qty_total')
      ]);
    })->values();
    
    Login or Signup to reply.
  2. Feeding a 2-element array to the groupBy() method only makes more work/handling because it generates an unnecessarily deep structure. Notice how Mohammad’s snippet has to reindex (values()), then call first(), then first() against just to traverse to the desired level.

    Instead, feed groupBy() a callback function to form a "composite string key" and keep the grouped data shallow.

    Code: (PHPize Demo)

    var_export(
        $stocks
        ->groupBy(fn($row) => $row['sku'] . '_' . $row['batch'])
        ->map(fn($set) => array_merge($set->first(), ['qty_total' => $set->sum('qty_total')]))
        ->values()
        ->toArray()
    );
    

    Output:

    array (
      0 => 
      array (
        'sku' => '123',
        'batch' => '123',
        'qty_total' => 4,
      ),
      1 => 
      array (
        'sku' => '1233',
        'batch' => '123',
        'qty_total' => 2,
      ),
      2 => 
      array (
        'sku' => '5',
        'batch' => '123',
        'qty_total' => 4,
      ),
    )
    

    Topically related content:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search