Search code examples
phpjsonlaravellaravel-collection

Laravel: Count integer value based on week of the month


I'm trying to count integer value from JSON: https://pomber.github.io/covid19/timeseries.json and got what I expected.

{
"date": [
"22 Jan",
"23 Jan",
"24 Jan",
"25 Jan",
....
],
"total_confirmed": [
555,
653,
941,
1434,
....
],
"total_deaths": [
17,
18,
26,
42,
....
],
"total_recovered": [
28,
30,
36,
39,
....
],
"max_value_of_total_confirmed": 272166
}

Here's my controller:

$client = new Client();$request = $client->get('https://pomber.github.io/covid19/timeseries.json');
$response = $request->getBody()->getContents();
$posts_dates = json_decode($response, true);

$confirmed_array = array();
$deaths_array = array();
$recovered_array = array();

if ( ! empty( $posts_dates ) ) {
    foreach ( $posts_dates as $country => $data )   {
        foreach ( $data as $dataKey => $dateData )    {

            $date = new \DateTime( $dateData['date'] );
            $day = $date->format( 'd M' );

            if ( !isset($confirmed_array[$day]) )  {
                $confirmed_array[$day] = 0;
            }
            $confirmed_array[$day] += $dateData['confirmed'];
        }
        foreach ( $data as $dataKey => $dateData )    {

            $date = new \DateTime( $dateData['date'] );
            $day = $date->format( 'd M' );

            if ( !isset($deaths_array[$day]) )  {
                $deaths_array[$day] = 0;
            }
            $deaths_array[$day] += $dateData['deaths'];
        }
        foreach ( $data as $dataKey => $dateData )    {

            $date = new \DateTime( $dateData['date'] );
            $day = $date->format( 'd M' );

            if ( !isset($recovered_array[$day]) )  {
                $recovered_array[$day] = 0;
            }
            $recovered_array[$day] += $dateData['recovered'];
        }
    }
}

$output = [
            "date" => array_keys($confirmed_array),
            "total_confirmed" => array_values($confirmed_array),
            "total_deaths" => array_values($deaths_array),
            "total_recovered" => array_values($recovered_array),
            "max_value_of_total_confirmed" => max($confirmed_array)
        ];

return $output;

What I'm trying to get is grouping those data not by date, but by week of the month (W3 Jan, W4 Jan, W1 Feb, W2 Feb, etc). Any help would be appreciated :)

Thank you.


Solution

  • I would recommend using collection. You can easily manage using the methods provided by Laravel.

    Group By Day

    $client = new Client();
    $request = $client->get('https://pomber.github.io/covid19/timeseries.json');
    $response = $request->getBody()->getContents();
    $posts_dates = json_decode($response, true);
    
    /****** Here we go ******/
    $posts_dates = collect($posts_dates)
        ->flatten(1)
        ->groupBy('date')
        ->map(function ($item, $key) {
            $item = collect($item);
            $date = \Carbon\Carbon::parse($key);
            $key  = 'W' . $date->weekOfMonth . $date->format(' M');
    
            return [
                'date'            => $key,
                'total_confirmed' => $item->sum('confirmed'),
                'total_deaths'    => $item->sum('deaths'),
                'total_recovered' => $item->sum('recovered'),
            ];
        })
        ->groupBy(function ($item, $key) {
            return collect($item)->keys()->all();
        })
        ->map(function ($item, $key) {
            return $item->map(function ($item) use ($key) {
                return $item[$key];
            });
        });
    
    $posts_dates->put('max_value_of_total_confirmed', $posts_dates['total_confirmed']->max());
    
    dd($posts_dates->toArray());
    

    Result

    array:5 [
      "date" => array:59 [
        0 => "W4 Jan"
        1 => "W4 Jan"
        2 => "W4 Jan"
        3 => "W4 Jan"
        4 => "W4 Jan"
        5 => "W4 Jan"
        6 => "W4 Jan"
        7 => "W5 Jan"
        8 => "W5 Jan"
        9 => "W5 Jan"
        10 => "W1 Feb"
        11 => "W1 Feb"
        12 => "W1 Feb"
        13 => "W1 Feb"
        14 => "W1 Feb"
        15 => "W1 Feb"
        16 => "W1 Feb"
        17 => "W2 Feb"
        18 => "W2 Feb"
        19 => "W2 Feb"
        20 => "W2 Feb"
        21 => "W2 Feb"
        22 => "W2 Feb"
        23 => "W2 Feb"
        24 => "W3 Feb"
        25 => "W3 Feb"
        26 => "W3 Feb"
        27 => "W3 Feb"
        28 => "W3 Feb"
        29 => "W3 Feb"
        30 => "W3 Feb"
        31 => "W4 Feb"
        32 => "W4 Feb"
        33 => "W4 Feb"
        34 => "W4 Feb"
        35 => "W4 Feb"
        36 => "W4 Feb"
        37 => "W4 Feb"
        38 => "W5 Feb"
        39 => "W1 Mar"
        40 => "W1 Mar"
        41 => "W1 Mar"
        42 => "W1 Mar"
        43 => "W1 Mar"
        44 => "W1 Mar"
        45 => "W1 Mar"
        46 => "W2 Mar"
        47 => "W2 Mar"
        48 => "W2 Mar"
        49 => "W2 Mar"
        50 => "W2 Mar"
        51 => "W2 Mar"
        52 => "W2 Mar"
        53 => "W3 Mar"
        54 => "W3 Mar"
        55 => "W3 Mar"
        56 => "W3 Mar"
        57 => "W3 Mar"
        58 => "W3 Mar"
      ]
      "total_confirmed" => array:59 [
        0 => 555
        1 => 653
        2 => 941
        3 => 1434
        4 => 2118
        5 => 2927
        6 => 5578
        7 => 6166
        8 => 8234
        9 => 9927
        10 => 12038
        11 => 16787
        12 => 19881
        13 => 23892
        14 => 27635
        15 => 30817
        16 => 34391
        17 => 37120
        18 => 40150
        19 => 42762
        20 => 44802
        21 => 45221
        22 => 60368
        23 => 66885
        24 => 69030
        25 => 71224
        26 => 73258
        27 => 75136
        28 => 75639
        29 => 76197
        30 => 76823
        31 => 78579
        32 => 78965
        33 => 79568
        34 => 80413
        35 => 81395
        36 => 82754
        37 => 84120
        38 => 86011
        39 => 88369
        40 => 90306
        41 => 92840
        42 => 95120
        43 => 97882
        44 => 101784
        45 => 105821
        46 => 109795
        47 => 113561
        48 => 118592
        49 => 125865
        50 => 128343
        51 => 145193
        52 => 156094
        53 => 167446
        54 => 181527
        55 => 197142
        56 => 214910
        57 => 242708
        58 => 272166
      ]
      "total_deaths" => array:59 [
        0 => 17
        1 => 18
        2 => 26
        3 => 42
        4 => 56
        5 => 82
        6 => 131
        7 => 133
        8 => 171
        9 => 213
        10 => 259
        11 => 362
        12 => 426
        13 => 492
        14 => 564
        15 => 634
        16 => 719
        17 => 806
        18 => 906
        19 => 1013
        20 => 1113
        21 => 1118
        22 => 1371
        23 => 1523
        24 => 1666
        25 => 1770
        26 => 1868
        27 => 2007
        28 => 2122
        29 => 2247
        30 => 2251
        31 => 2458
        32 => 2469
        33 => 2629
        34 => 2708
        35 => 2770
        36 => 2814
        37 => 2872
        38 => 2941
        39 => 2996
        40 => 3085
        41 => 3160
        42 => 3254
        43 => 3348
        44 => 3460
        45 => 3558
        46 => 3802
        47 => 3988
        48 => 4262
        49 => 4615
        50 => 4720
        51 => 5404
        52 => 5819
        53 => 6440
        54 => 7126
        55 => 7905
        56 => 8733
        57 => 9867
        58 => 11299
      ]
      "total_recovered" => array:59 [
        0 => 28
        1 => 30
        2 => 36
        3 => 39
        4 => 52
        5 => 61
        6 => 107
        7 => 126
        8 => 143
        9 => 222
        10 => 284
        11 => 472
        12 => 623
        13 => 852
        14 => 1124
        15 => 1487
        16 => 2011
        17 => 2616
        18 => 3244
        19 => 3946
        20 => 4683
        21 => 5150
        22 => 6295
        23 => 8058
        24 => 9395
        25 => 10865
        26 => 12583
        27 => 14352
        28 => 16121
        29 => 18177
        30 => 18890
        31 => 22886
        32 => 23394
        33 => 25227
        34 => 27905
        35 => 30384
        36 => 33277
        37 => 36711
        38 => 39782
        39 => 42716
        40 => 45602
        41 => 48228
        42 => 51170
        43 => 53796
        44 => 55865
        45 => 58358
        46 => 60694
        47 => 62494
        48 => 64404
        49 => 67003
        50 => 68324
        51 => 70251
        52 => 72624
        53 => 76034
        54 => 78088
        55 => 80840
        56 => 83207
        57 => 84854
        58 => 87256
      ]
      "max_value_of_total_confirmed" => 272166
    ]
    

    Group By Week

    $client = new Client();
    $request = $client->get('https://pomber.github.io/covid19/timeseries.json');
    $response = $request->getBody()->getContents();
    $posts_dates = json_decode($response, true);
    
    /****** Here we go ******/
    $posts_dates = collect($posts_dates)
        ->flatten(1)
        ->map(function ($item) {
            $date         = \Carbon\Carbon::parse($item['date']);
            $item['week'] = 'W' . $date->weekOfMonth . $date->format(' M');
    
            return $item;
        })
        ->groupBy('week')
        ->map(function ($item, $key) {
            $item = collect($item);
    
            return [
                'date'            => $key,
                'total_confirmed' => $item->sum('confirmed'),
                'total_deaths'    => $item->sum('deaths'),
                'total_recovered' => $item->sum('recovered'),
            ];
        })
        ->groupBy(function ($item, $key) {
            return collect($item)->keys()->all();
        })
        ->map(function ($item, $key) {
            return $item->map(function ($item) use ($key) {
                return $item[$key];
            });
        });
    
    $posts_dates->put('max_value_of_total_confirmed', $posts_dates['total_confirmed']->max());
    
    dd($posts_dates->toArray());
    

    Result

    array:5 [
      "date" => array:10 [
        0 => "W4 Jan"
        1 => "W5 Jan"
        2 => "W1 Feb"
        3 => "W2 Feb"
        4 => "W3 Feb"
        5 => "W4 Feb"
        6 => "W5 Feb"
        7 => "W1 Mar"
        8 => "W2 Mar"
        9 => "W3 Mar"
      ]
      "total_confirmed" => array:10 [
        0 => 14206
        1 => 24327
        2 => 165441
        3 => 337308
        4 => 517307
        5 => 565794
        6 => 86011
        7 => 672122
        8 => 897443
        9 => 1275899
      ]
      "total_deaths" => array:10 [
        0 => 372
        1 => 517
        2 => 3456
        3 => 7850
        4 => 13931
        5 => 18720
        6 => 2941
        7 => 22861
        8 => 32610
        9 => 51370
      ]
      "total_recovered" => array:10 [
        0 => 353
        1 => 491
        2 => 6853
        3 => 33992
        4 => 100383
        5 => 199784
        6 => 39782
        7 => 355735
        8 => 465794
        9 => 490279
      ]
      "max_value_of_total_confirmed" => 1275899
    ]