Sort by timestamp, then set certain elements as first

Given this collection:

$payments = [{
    "timestamp": "2021-03-10 21:19:10",
    "amount": "100",
    "currency":"eur"
},
{
    "timestamp": "2021-03-10 22:11:10",
    "amount": "100",
    "currency":"gbp"
},
{
    "timestamp": "2021-03-10 23:19:10",
    "amount": "100",
    "currency":"usd"
},
{
    "timestamp": "2021-03-10 22:19:10",
    "amount": "100",
    "currency":"gbp"
}]

I want to sort it in a way that payments will be sorted by timestamp, but starting with certain currency. For example gbp.

$payments = [{
    "timestamp": "2021-03-10 22:11:10",
    "amount": "100",
    "currency":"gbp"
},
{
    "timestamp": "2021-03-10 22:19:10",
    "amount": "100",
    "currency":"gbp"
}
{
    "timestamp": "2021-03-10 21:19:10",
    "amount": "100",
    "currency":"eur"
},
{
    "timestamp": "2021-03-10 23:19:10",
    "amount": "100",
    "currency":"usd"
}]

Right now I’m doing it in a way that I am taking first, sorted collection where currency is gbp and then I’m merging to it sorted collection where currency is not gbp. Like this:

$paymentsInSameCurrency = $payments
    ->where('currency',$currency)
    ->sortBy('timestamp');

$paymentsInDifferentCurrency = $payments
    ->where('currency','!=',$currency)
    ->sortBy('timestamp');

$payments = $paymentsInSameCurrency->merge($paymentsInDifferentCurrency);

Is there a way to make it more efficient?

Answer

Simplified version could be something like this:

 $payments = $payments
    ->sortByDesc(DB::raw("currency = '$currency'")); // first when it's true
    ->sortBy('timestamp');                            // second level sorting by timestamp

Leave a Reply

Your email address will not be published. Required fields are marked *