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.
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()
again 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: