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
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
}