Collections - how to reformat my collection to desired format?

Hello everyone, I have following collection:

'[
	{
		"id": 436969,
		"release_date": "2016-04-26T00:00:00+0000",
		"title": "A"
	},
	{
		"id": 437005,
		"release_date": "2016-01-09T00:00:00+0000",
		"title": "B"
	},
	{
		"id": 438603,
		"release_date": "2012-12-31T00:00:00+0000",
		"title": "C"
	},
	{
		"id": 438223,
		"release_date": "2012-12-29T00:00:00+0000",
		"title": "D"
	},
]'

As you can see one title has been released in 2016-04, one in 2016-01 and two titles in 2012-12.
I need to reformat it to the following format (grouped by release year and month):

{
	"2016": { // YEAR
		"04": { // MONTH
			"0": {
				"id": 436969,
				"release_date": "2016-04-26T00:00:00+0000",
				"title": "A"
			}
		},
		"01": { // MONTH
			"0": {
				"id": 437005,
				"release_date": "2016-01-09T00:00:00+0000",
				"title": "B"
			}
		}
	},
	"2012": { // YEAR
		"12": { // MONTH
			"0": {
				"id": 438603,
				"release_date": "2012-12-31T00:00:00+0000",
				"title": "C"
			},
			"1": {
				"id": 438223,
				"release_date": "2012-12-29T00:00:00+0000",
				"title": "D"
			}
		}
	}
}

How I can do this with Collections?

I know how to group it by year or month (year example):

$combinedByYear = (new Collection($documents))->combine(
    'id',
    function ($document) { return $document; },
    function ($document) { return $document->release_date->year; }
);

But I do not have idea how I can add months level to it. Please help.

You just need to group the internal results again:

collection($data)
    ->groupBy(function ($e) { return $e->release_date->year; })
    ->map(function ($group) {
        return collection($group)->groupBy(function ($e) {
              return $e->release_date->month;
         });
    })
3 Likes

Perfect! Collections are so powerfull, I hope I will learn some day how to use them properly. Thank you.