Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

vincent15000's avatar

How to structure the results from the collection ?

Hello,

I have a collection of sessions, each session has an id, a date, and many other properties.

"id": 861,
"date": "2023-08-07T09:00:00.000000Z",
...

I need to sort all these sessions like this.

{
		"year": 2022,
		"weeks": {
				"week": 21,
				"dates": {
						"date": "2022-08-07",
						"sessions": {
								{
										"id": 861,
										"date": "2023-08-07T09:00:00.000000Z"
										...
								},
								{
										"id": 862,
										"date": "2023-08-07T10:30:00.000000Z"
										...
								},
								...
						}
				}
		}
},
{
		"year": 2023,
		"weeks": {
				...
		}
}

I have tried several ways to achieve this :

  • map to groups : but I need to map to groups inside map to groups inside map to groups, so I need to write several loops

  • create manually the output : I extract the years, then for each year I extract the weeks, then for each week, I extract the dates, and for each date I extract the sessions

I'm sure that there is an easier way to format the output with the needed structure, but how ?

How would you do that ?

Thanks for your help.

V

0 likes
2 replies
vincent15000's avatar
vincent15000
OP
Best Answer
Level 63

I just solved the problem like this.

$structuredSessions = collect($sessions
    ->groupBy(function ($session) {
        return [
            'year' => date('Y', strtotime($session['date'])),
        ];
    })
    ->map(function ($sessions, $year) {
        return [
            'year' => $year,
            'weeks' => $sessions
                ->groupBy(function ($session) {
                    return [
                        'week_number' => date('W', strtotime($session['date'])),
                    ];
                })
                ->map(function ($sessions, $weekNumber) use ($year) {
                    return [
                        'week_number' => $weekNumber,
                        'start_of_week' => Carbon::now()->setISODate($year, $weekNumber)->startOfWeek()->isoFormat('DD/MM'),
                        'end_of_week' => Carbon::now()->setISODate($year, $weekNumber)->endOfWeek()->isoFormat('DD/MM'),
                        'dates' => $sessions
                            ->groupBy(function ($session) {
                                return [
                                    'date' => Str::ucfirst(Carbon::parse($session->date)->locale('fr_FR')->isoFormat('dddd DD/MM')),
                                ];
                            })
                            ->map(function ($sessions, $key) {
                                return [
                                    'date' => $key,
                                    'sessions' => $sessions,
                                ];
                            })
                            ->values(),
                    ];
                })
                ->values(),
        ];
    })
    ->values()
);

If you have any better suggestions, don't hesitate to share your ideas ;).

Please or to participate in this conversation.