Combining multiple objects that use the same identifier

I am trying to combine several objects (e.g. receipts, reports, etc.) using Collection->merge() .

This is the code I used:

 $receipts = Receipt::all(); $reports = Report::all(); $collection = $receipts->merge($reports); 

This is the result:

enter image description here

The above screenshot shows two elements, but the third element is missing because it has the same identifier (id: "1") as the first. What I'm trying to achieve is to display all three of them in a collection.

EDIT:

I need the result as an object (collection), because I also use the code in my view, where I check the class to determine what to display. In addition, I use this function to sort objects in a collection.

  $collection->sort(function($a, $b) { $a = $a->created_at; $b = $b->created_at; if ($a === $b) { return 0; } return ($a > $b) ? 1 : -1; }); 
+7
source share
4 answers

I know this is an old question, but I will still provide an answer to the case if someone comes here from a search like me.

If you try to combine two different eloquent collections into one, and some objects will have the same identifier, one will overwrite the other. I do not know why this is happening, and if this is a mistake or feature, more research is needed. To fix this, simply use the push () method or rethink your approach to the problem to avoid this.

Example problem:

 $cars = Car::all(); $bikes = Bike::all(); $vehicles = $cars->merge($bikes); // if there is a car and a bike with the same id, one will overwrite the other 

Possible Solution:

 $collection = collect(); $cars = Car::all(); $bikes = Bike::all(); foreach ($cars as $car) $collection->push($car); foreach ($bikes as $bike) $collection->push($bike); 

Source: https://medium.com/@tadaspaplauskas/quick-tip-laravel-eloquent-collections-merge-gotcha-moment-e2a56fc95889

+8
source

I know that I stumble upon a 4-year-old thread, but I came across this and none of the answers was what I was looking for; so, like @Tadas, I will leave my answer to people who come across this. After carefully studying the laravel 5.5 documentation, I found that concat was a go-to method. Thus, in the case of OP, the correct solution would be:

 $receipts = Receipt::all(); $reports = Report::all(); $collection = $receipts->concat($reports); 

Thus, each element of the Report collection will be added to each element of the Receipts collection, if some fields are identical.

In the end, you can shuffle it to get a more visual attractive result, for example. view:

 $collection->shuffle(); 
+3
source

You can put all collections in an array and use this. Depends on what you want to do with the collection.

 $list = array(); $list = array_merge($list, Receipt::all()->toArray()); $list = array_merge($list, Report::all()->toArray()); 
0
source

Another way to do this is to convert one of your collections to a base collection using the toBase () method. You can find it in Illuminate\Support\Collection

Method Definition:

 /** * Get a base Support collection instance from this collection. * * @return \Illuminate\Support\Collection */ public function toBase() { return new self($this); } 

Using:

 $receipts = Receipt::all(); $reports = Report::all(); $collection = $receipts->toBase()->merge($reports); 
0
source

Source: https://habr.com/ru/post/1203473/


All Articles