ahinkle
ahinkle

Reputation: 2261

Laravel merge multiple collections and sort by corresponding datetime field

I have multiple collections merging into one, then sorting that one by datetime to ultimately create a timeline between the collections.

Heres the catch, the datetime columns to sort are different names.

Is there anything I can do to make this cleaner - possibly attach the foreach loop with the ->merge? Looks ugly with the foreach loop. note: code below works but I feel it's a lazy way out and might be slow with more items in the collection.

// Create timeline, sortby creation datetimes.
$TimelineItems = collect();

$TimelineItems = $Appointments->merge($lead->SalesResult);
foreach ($TimelineItems as $key => $TimelineItem) {
    if(!empty($TimelineItem->appointment_created)) {
        $TimelineItems[$key]->created_at = $TimelineItem->appointment_created;
    }
    if(!empty($TimelineItem->salesresult_created_timestamp)) {
        $TimelineItems[$key]->created_at = $TimelineItem->salesresult_created_timestamp;
    }
}
$TimelineItems = $TimelineItems->sortByDesc('created_at');
dd($TimelineItems);

Upvotes: 0

Views: 1655

Answers (1)

Luke Waite
Luke Waite

Reputation: 2475

The best solution would probably be to standardize your model objects to use standard date stamp fields - then you wouldn't need to transform them.

Failing that, you could use each() or transform():

// Create timeline, sortby creation datetimes.
$TimelineItems = collect();
$AppointmentTemps = collect($Appointments);
$SalesResultTemps = $lead->SalesResult;

$TimelineItems = $AppointmentTemps
    ->merge($SalesResultTemps)
    ->transform( function ($item) {
        if(!empty($item->appointment_created)) {
            $item->created_at = $item->appointment_created;
        }
        if(!empty($item->salesresult_created_timestamp)) {
            $item->created_at = $item->salesresult_created_timestamp;
        }

        return $item;
    })
    ->sortByDesc('created_at');

dd($TimelineItems);

The transform method iterates over the collection and calls the given callback with each item in the collection. The items in the collection will be replaced by the values returned by the callback:

See the docs for the transform() collection method for reference.

Upvotes: 1

Related Questions