I suggest you do the in your database query instead of mapping over the result with php.
So if you supply some sample data and the expected result we might be able to help you.
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
Hello, I want to group by a collection by value without setting the key as the key (:D) , Edited: My tables structures:
-Users(id,firstname,lastname,...)
-Events(id,type,fromDate,endDate,...)
-Sport(id,event_id,nbMax,coverImg,...) -> event_id references events(id)
-Challenge(id,event_id,nbMax,address,...) -> event_id references events(id)
-Sensitization(id,event_id,patient...) -> event_id references events(id)
-Registrations(id,event_id,user_id)
My objective is to calculate the percentage of registrations for each type of event compared to nbMax in a given year(for the event start), I did:
Event::whereIn('type', $request->filter)
->select('events.id', 'events.type', 'events.fromDate')
->whereYear('events.fromDate', $request->year)
->orderBy('events.fromDate')
->withCount('registration')
->get()
->map(function ($query) {
$event = $query->Sport ?: ($query->Challenge ?: 0);
$query->nbMax = $event ? $event->nbMax : 1;
return $query;
});
returning :
[
{
"id": 115,
"type": 3,
"fromDate": "2021-05-27 00:00:00",
"registration_count": 4,
"nbMax": 10
},
{
"id": 117,
"type": 3,
"fromDate": "2021-05-27 00:00:00",
"registration_count": 7,
"nbMax": 12
},
{
"id": 120,
"type": 4,
"fromDate": "2021-05-30 00:00:00",
"registration_count": 1,
"nbMax": 10
},
{
"id": 121,
"type": 4,
"fromDate": "2021-05-30 00:00:00",
"registration_count": 3,
"nbMax": 10
}
]
I grouped this data by type then by fromDate, This is how I did :
$filterResult = $result->groupBy(['type', function ($item) {
return Carbon::parse($item->fromDate)->format('Y-m-d');
}])
I got this :
{
"3": {
"2021-05-27": [
{
"id": 115,
"type": 3,
"fromDate": "2021-05-27 00:00:00",
"registration_count": 4,
"nbMax": 10
},
{
"id": 117,
"type": 3,
"fromDate": "2021-05-27 00:00:00",
"registration_count": 7,
"nbMax": 12
}
]
},
"4":{
"2021-05-30":[
{
"id": 120,
"type": 4,
"fromDate": "2021-05-27 00:00:00",
"registration_count": 4,
"nbMax": 10
},
{
"id": 121,
"type": 4,
"fromDate": "2021-05-27 00:00:00",
"registration_count": 7,
"nbMax": 12
},
]
}
}
then I did added a map like this :
->map(function ($query) {
return $query->map(function ($item) {
return (collect($item)->sum('registration_count') * 100) / collect($item)->sum('nbMax');
});
});
and i got like this:
{
"3": {
"2021-05-27": 3.125
},
"4": {
"2021-05-30": 3.125
},
}
But the output i want is far away from the result :) :
{
"3": [
{
"fromDate":"2021-05-27",
"sum":3.125
}
],
"4": [
{
"fromDate":"2021-05-30",
"sum":3.125
}
]
}
What I wanted in the final output is to group by without setting the key and returning and object instead of a simple value so I changed the map To:
->map(function ($query) {
return $query->map(function ($item) {
return [
"date"=>Carbon::parse($item[0]->fromDate)->translatedFormat('Y-m-d'),
"sum"=>(collect($item)->sum('registration_count') * 100) / collect($item)->sum('nbMax')
];
});
});
I got this result :
{
"3": {
"2021-05-27":
{
"fromDate":"2021-05-27",
"sum":3.125
}
},
"4": {
"2021-05-30":
{
"fromDate":"2021-05-30",
"sum":3.125
}
}
}
Then I added ->values()->toArray(); after the map so the result become as expected:
{
"3": [
{
"fromDate":"2021-05-27",
"sum":3.125
}
],
"4": [
{
"fromDate":"2021-05-30",
"sum":3.125
}
]
}
Please or to participate in this conversation.