Search code examples
laraveleloquentlaravel-10

How to get the sum in array of objects in Laravel 10?


I have this Array of objects where I wanna sum up the quantity having the same 'barcode' field and if it has a different 'location' field it should be separated.

here is my sample object

[
  {
    "id": 1,
    "barcode": "555",
    "description": "pencil",
    "quantity": "3",
    "location": "drawer1",
  },
  {
    "id": 2,
    "barcode": "555",
    "description": "pencil",
    "quantity": "1",
    "location": "drawer1",
  },
  {
    "id": 3,
    "barcode": "123",
    "description": "paper",
    "quantity": "1",
    "location": "drawer2",
  },
  {
    "id": 4,
    "barcode": "123",
    "description": "paper",
    "quantity": "8",
    "location": "drawer2",
  },
  {
    "id": 5,
    "barcode": "123",
    "description": "paper",
    "quantity": "8",
    "location": "drawer1",
  },

]

and here is my desired result.

[
  {
    "id": 1,
    "barcode": "555",
    "description": "pencil",
    "quantity": "4",
    "location": "drawer1",
  },
  {
    "id": 2,
    "barcode": "123",
    "description": "paper",
    "quantity": "9",
    "location": "drawer2",
  },
  {
    "id": 3,
    "barcode": "123",
    "description": "paper",
    "quantity": "8",
    "location": "drawer1",
  },

]

just for additional information, I got this code from my previous question but now I am clueless on how to integrate this location field.

$collection
    ->groupBy('barcode')
    ->map(fn ($group, $key) => [
        'id' => $group->first()['id'],
        'barcode' => $group->first()['barcode'],
        'description' => $group->first()['description'],
        'qty' => $group->sum('qty'),
    ])
    ->values();

Thanks, and hopefully someone will be able to point out what am missing here.


Solution

  • If you follow this map loop, you should receive the expected results.

    $data = collect(json_decode($jsonInput, true));
                  
        $grouped = $data->groupBy(function ($item) {
            return $item['barcode'] . '_' . $item['location'];
        })->map(function ($group) {
            return [
                'id' => $group->first()['id'],
                'barcode' => $group->first()['barcode'],
                'description' => $group->first()['description'],
                'quantity' => $group->sum('quantity'),
                'location' => $group->first()['location'],
            ];
        })->values()->each(function ($item, $index) {
            $item['id'] = $index + 1;
        });
        
        $jsonOutput = $grouped->toJson();