Sorting Laravel Collection via Array of ID's
You can do this:
$order = $list->item_order;
$list->items->sortBy(function($model) use ($order){
return array_search($model->getKey(), $order);
}
Also you could add an attribute accessor to your model which does the same
public function getSortedItemsAttribute()
{
if ( ! is_null($this->item_order)) {
$order = $this->item_order;
$list = $this->items->sortBy(function($model) use ($order){
return array_search($model->getKey(), $order);
});
return $list;
}
return $this->items;
}
Usage:
foreach ($list->sortedItems as $item) {
// More Code Here
}
If you need this sort of functionality in multiple places I suggest you create your own Collection class:
class MyCollection extends Illuminate\Database\Eloquent\Collection {
public function sortByIds(array $ids){
return $this->sortBy(function($model) use ($ids){
return array_search($model->getKey(), $ids);
}
}
}
Then, to actually use that class override newCollection()
in your model. In this case it would be in the ChecklistItems
class:
public function newCollection(array $models = array())
{
return new MyCollection($models);
}
sort a collection according to an array of IDs in Laravel
You probably have not responded because of differences between config('settings.data_grids') And $categories. So edit your code as follows
Please add these three lines to your code:
$catIds = $categories->pluck('cat_id')->toArray(); //get all cat_id
$diff = array_diff($catIds, $grids_arr); // difference array from query
$grids_arr = array_merge($grids_arr , $diff); //merge difference with array
for example:
$categories = Category::select('*')->get(); //for example
$array = [
[
"pos" => "0",
"col" => "1",
"row" => "1",
"size_x" => "2",
"size_y" => "1",
"cat_id" => 1,
],
[
"pos" => "0",
"col" => "1",
"row" => "2",
"size_x" => "2",
"size_y" => "1",
"cat_id" => 10,
]
];
$grids = collect($array);
if ($grids->isNotEmpty()) {
$grids_arr = $grids->pluck("cat_id")->toArray();
$grids_arr = array_map('intval', $grids_arr);
//Please add these three lines to your code
$catIds = $categories->pluck('cat_id')->toArray();
$diff = array_diff($catIds, $grids_arr);
$grids_arr = array_merge($grids_arr, $diff);
//-----
$sorted = $categories->sortBy(function ($model) use ($grids_arr) {
return array_search($model->cat_id, $grids_arr);
});
return $sorted->values()->all();
}
Laravel Sort Collection By Dynamic ID array
Collections has a sortBy function that takes a custom callback:
$people_collection = People::find($people)
->sortBy(function($person, $key) use($people) {
return array_search($person->id, $people);
});
See the docs.
Laravel Eloquent - Sort Collection by Column by Array's Order
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,
],
]
Laravel Sort Parent Collection by their relationship values
There is an SQL approach, that would look something like this. Create an subselect, fetch the date you want to use and order by it.
Event::with(['slots' => function ($q) {
$q->orderBy('date');
$q->orderBy('start_time');
}])
->addSelect([
'date' => Comment::selectRaw('MAX(start_date)')
->whereColumn('events.id', 'comments.event_id'),
])->orderBy('date');
Simply use Laravel relation and do the same, not as performance optimized but very straight forward aproeach.
$events = Event::with(['slots' => function ($q) {
$q->orderBy('date');
$q->orderBy('start_time');
}])->active()->get();
$events->sortBy(function ($event) {
return $event->slots()->max('start_date');
});
sort a laravel collection by another array
Get all IDs from your $slideOrderSetting
:
$slideOrderArray = json_decode($slideOrderSetting, true);
$slideOrderIDs = collect($slideOrderArray)->pluck('id')->toArray()
About pluck()
method
Then get slides:
$slides = DB::table('homepage_slides')
->orderByRaw(DB::raw('FIELD(id, '.implode(', ', $slideOrderIDs).')'))
->paginate(10)
or
$slides = DB::table('homepage_slides')
->whereIn('id', $slideOrderIDs)
->orderByRaw(DB::raw('FIELD(id, '.implode(', ', $slideOrderIDs).')'))
->paginate(10)
Related Topics
Get the Sum of All Digits in a Numeric String
JSON_Encode Function: Special Characters
How to Turn Off PHP Safe_Mode Off for a Particular Directory in a Shared Hosting Environment
Using X-Sendfile with Apache/Php
Best Way to Get Files from a Dir Filtered by Certain Extension in PHP
PHP Curl Localhost Is Slow When Making Concurrent Requests
Send Cookie with File_Get_Contents
PHP Move_Uploaded_File() Fails Without Reason
The Post Method Is Not Supported for This Route. Supported Methods: Get, Head. Laravel
Linux and Oracle Instant Client
How to Get Rid of MySQL Error 'Prepared Statement Needs to Be Re-Prepared'
Access PHP Variable in JavaScript