Tomas C. Lopes
Tomas C. Lopes

Reputation: 109

Laravel Eloquent - Sort Collection by Column by Array's Order

I want to be able to sort the results of my collection by the status column in specific order.

The idea is to paginate the collection but giving priority in a specific order: [2, 1, ...], so the pending listings are shown first and the other after!

Does anyone has an idea on such method?

Thanks in advance.

Upvotes: 4

Views: 8819

Answers (2)

CBrach
CBrach

Reputation: 107

If your status priority is not in numeric order (e.g. 2 > 1 > 3 > 0), you can alternatively pass a callback function to sortBy:

$collection = collect([
    ['name' => 'A', 'status' => 0],
    ['name' => 'B', 'status' => 3],
    ['name' => 'C', 'status' => 0],
    ['name' => 'D', 'status' => 1],
    ['name' => 'E', 'status' => 2],
    ['name' => 'F', 'status' => 1],
    ['name' => 'G', 'status' => 3],
    ['name' => 'H', 'status' => 1],
    ['name' => 'I', 'status' => 2],
    ['name' => 'J', 'status' => 3],
]);

// define status priority here
$statusPriorities = [2, 1, 3, 0];

$collection->sortBy(function($order) use($statusPriorities){
   return array_search($order['status'], $statusPriorities);
})->values()->all();

Output:

[
     [
       "name" => "I",
       "status" => 2,
     ],
     [
       "name" => "E",
       "status" => 2,
     ],
     [
       "name" => "D",
       "status" => 1,
     ],
     [
       "name" => "F",
       "status" => 1,
     ],
     [
       "name" => "H",
       "status" => 1,
     ],
     [
       "name" => "B",
       "status" => 3,
     ],
     [
       "name" => "G",
       "status" => 3,
     ],
     [
       "name" => "J",
       "status" => 3,
     ],
     [
       "name" => "A",
       "status" => 0,
     ],
     [
       "name" => "C",
       "status" => 0,
     ],
   ]

Upvotes: 9

Akhtar Munir
Akhtar Munir

Reputation: 1769

Referring to laravel documentation https://laravel.com/docs/7.x/collections#method-sortby you can sort collection by column like...

$tasks = App\Task::all();
$tasks1 = $tasks->sortBy('title');
return $tasks1->values()->all();
//values() method is used to preserve array original keys
//You can also user sortByDesc, to get reverse order of your collection.

As you can see it has been sorted by title in asc order

[
    {
        "id": 5,
        "title": "Akhtar",
        "created_at": "2019-09-01 14:18:05",
        "updated_at": "2019-09-01 14:18:05"
    },
    {
        "id": 6,
        "title": "Hamid khan",
        "created_at": "2019-09-01 14:18:05",
        "updated_at": "2019-09-01 19:19:18"
    },
    {
        "id": 7,
        "title": "Zarif",
        "created_at": "2019-09-04 19:14:18",
        "updated_at": "2019-09-04 19:14:18"
    },
    {
        "id": 1,
        "title": "testing",
        "created_at": "2019-09-01 13:01:39",
        "updated_at": "2019-09-01 13:01:39"
    }
]

Upvotes: 1

Related Questions