Skip to content
Advertisement

Laravel group by change keys

Hi I have reservations and their start times. Now I need to raport it.

        $monthlyAmounts = Reservation::all()
        ->groupBy(function ($proj) {
            return cdate($proj->start_time)->format('Y-m');
        })
        ->map(function ($month) {
            return $this->sumTime($month);
        });

sumTime is my function to calculate diff between start time and end time. cdate is helper -> carbon::parse($date)..

Result of this is:

array:2 [▼
  "2020-01" => 60
  "2020-02" => 420
]

Need

But for API it would be better to get like this:

[
    "2020" => [
        '01' => 60,
        '02' => 30
    ],
    "2021" => [
        '01' => 30,
    ]
]

My try

Unfortunately I can’t make it like that. I tried:

    $monthlyAmounts = Reservation::all()
        ->groupBy(function ($proj) {
            return cdate($proj->start_time)->format('Y-m');
        })
        ->map(function ($month) {
            return $this->sumTime($month);
        })
        ->mapToGroups(function ($item,$key) {
            $arrkey = explode('-',$key);
            return [$arrkey[0]=>[$arrkey[1]=>$item]];
        });

But It makes this:

array:1 [▼
  2020 => array:2 [▼
    0 => array:1 [▼
      "01" => 60
    ]
    1 => array:1 [▼
      "02" => 420
    ]
  ]
]

So I can’t do $res[‘2020′][’01’]. How to do It?

Advertisement

Answer

Try this:

$monthlyAmounts = Reservation::all()
        ->groupBy(function ($proj) {
            return cdate($proj->start_time)->format('Y');
        })
        ->map(function ($items) {
            return $items->groupBy(function($item) {
                return cdate($item->start_time)->format('m');
            })
            ->map(function($month) {
                return $this->sumTime($month);
            }); 
        });
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement