'How to KeyBy where multiple items have the same key

I am using Laravel Collections methods and am trying to key my query results (which are a collection) by the id. The problem is I have multiple entries with the same id, but point to different countries and I want to have all of the values, not just the last one.

Here is my code that i am using so far:

   $allCountries = new Collection($allCountries);

   $offerCountries = $allCountries->keyBy('id');

    dd($offerCountries);

    foreach ($offer as $o) {

       $o->countries = $allCountries->get($o->id);

    }

To explain, my query puts the results in $allCountries which contains ids and countries and those results looks something like this

id=>225, country=>US
id=>225, country=>IT
id=>3304, country=>NZ

Just to give you a quick idea. I want to key this by the id which results in $offerCountries. I then loop thru a previous Collection that contains offers which have a certain ID that relates to the country result by id. So for the offer 225, the countries it contains are US and IT. I loop thru each offer and set the countries object equal to all the $allCountries id that it equals. The problem I have here is keyBy overwrites the value and only takes the last one. I am hoping to get some results like this:

 [
   225 => countries: {'id' => 225, 'country' => 'US'}, {'id' =>           
   '225', 'country' => 'IT'}
    3304 => ['id' => 3304, 'country' => 'NZ'],
]

Is there a laravel method to do this, or do I need to write my own keyBy so it does not overwrite. If so, how can I get started to write this method?

Thanks



Solution 1:[1]

Instead of using keyBy, use groupBy:

$countriesById = collect($allCountries)->groupBy('id');

Solution 2:[2]

You could use filter and create a custom filter

$filtered = $allCountries->filter(function ($item) use ($id) {
    return $item->id == $id;
});

$filtered->all();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nick
Solution 2 Timothy Bracken