Home > OS >  How can I merge and sum simple Laravel Collections with the same keys?
How can I merge and sum simple Laravel Collections with the same keys?

Time:10-04

I have three Collections with the same keys and different numeric values, and I'd like to sum them together. e.g.

$broadInventory = {'horse': 300, 'cow': 400, 'entropy': 400};
$ericaInventory = {'horse': 10, 'cow': 20, 'entropy': 30};
$johnsonInventory = {'horse': 5, 'cow': 9, 'entropy': 3};

and I'm looking for this result:

{'horse': 315, 'cow': 429, 'entropy': 433};

I figured this would be easy, but it's turned out harder than I thought!

EDIT: Thanks to Abdulla, this is the answer I came up with:

    private function sumCollections(Collection ...$collections) {
        $merge = collect($collections);
        $keys = $collections[0]->keys();

        return $merge->pipe(
            static function ($item) use ($keys) {
                return collect([
                    $keys->mapWithKeys(fn($key) => [$key => $item->sum($key)])
                ]);
            }
        );
    }

CodePudding user response:

Bit tricky, but it works. By using enter image description here

CodePudding user response:

First of all, that is wrong array/collection syntax you wrote up there. convert all the collections to arrays using the toArray() function. Then use the array_merge_recursive() to merge the arrays so you get one single array with 3 keys. Then loop through the array and sum the values, appending each value to a the same array. Here is the explanation in code:

$broadInventory = collect(['horse' => 300, 'cow' => 400, 'entropy' => 400]);
$ericaInventory = collect(['horse' => 10, 'cow' => 20, 'entropy' => 30]);
$johnsonInventory = collect(['horse' => 5, 'cow' => 9, 'entropy' => 3]);

$broadInventory = $broadInventory->toArray();
$ericaInventory = $ericaInventory->toArray();
$johnsonInventory = $johnsonInventory->toArray();

$new_array = array_merge_recursive($broadInventory, $ericaInventory, $johnsonInventory);

foreach(array_keys($new_array) as $key) {
   
$new_array[$key] = array_sum($new_array[$key]);

}
$new_colection = collect($new_array);

dd($new_collection);


will give you:

^ Illuminate\Support\Collection {#1269 ▼
  #items: array:3 [▼
    "horse" => 315
    "cow" => 429
    "entropy" => 433
  ]
  #escapeWhenCastingToString: false
}
  • Related