@t0berius it doesnt seem strange for 31.12 to be at the end as it is after 07.01. If you want it before i would suggest using date as key in YY.MM.DD format
Jan 7, 2021
3
Level 13
sortCollection (special case on "year" switch)
The following code is used to generate a collection used to generate a chart:
$pastDays = 7;
$signUpsLastWeek = User::whereDate('created_at', '>=', now()->subDays($pastDays))->select('created_at')->get();
//group them now by date
$signUpsLastWeek = $signUpsLastWeek->groupBy(function($item) {
return $item->created_at->format('m.d');
});
//group them now by date now, using collection operations
$signUpsLastWeek = $signUpsLastWeek->mapWithKeys(function ($userGroup, $key) {
return [$key => $userGroup->count()];
});
//insert empty records inside collection for dates where no users signed up
for ($days_backwards = 0; $days_backwards <= $pastDays; $days_backwards++) {
if(!$signUpsLastWeek->has(today()->subDays($days_backwards)->format('m.d')))
$signUpsLastWeek->put(today()->subDays($days_backwards)->format('m.d'), 0);
}
//reverse order, so the latest records will be at the end of the collection (for graph rendering)
$signUpsLastWeek = $signUpsLastWeek->sortKeys(SORT_NUMERIC);
$signUpsLastWeek = $signUpsLastWeek->mapWithKeys(function ($item, $key) {
//make sure the key is formatted from MM.DD to DD.MM
return [explode(".", $key)[1] . "." . explode(".", $key)[0] => $item];
});
Running this code now returns a collection like:
Illuminate\Support\Collection {#1805 ▼
#items: array:8 [▼
"01.01" => 0
"02.01" => 0
"03.01" => 0
"04.01" => 0
"05.01" => 0
"06.01" => 0
"07.01" => 0
"31.12" => 0
]
}
Any idea how to fix?
The main advantage of using a collection is we only generate one SQL query, otherwise this would trigger one query for every day, using this approach was fine for us, but now because of the "switch" inside the months the chart seems strange, because 31.12 is listed at the end.
Please or to participate in this conversation.