Skip to content
Advertisement

PHP Group array by date

I have the following array that gathers data from purchases, visits and coupons generated in my application:


    array:10 [
      0 => array:2 [
        "dt" => "2020-11-18"
        "cupoms" => 9
      ]
      1 => array:2 [
        "dt" => "2020-11-19"
        "cupoms" => 1
      ]
      2 => {#1421 
        +"dt": "2020-11-14"
        +"visits": 1
      }
      3 => {#1423 
        +"dt": "2020-11-15"
        +"visits": 1
      }
      4 => {#860 
        +"dt": "2020-11-16"
        +"visits": 9
      }
      5 => {#530 
        +"dt": "2020-11-18"
        +"visits": 48
      }
      6 => {#1527 
        +"dt": "2020-11-19"
        +"visits": 3
      }
      7 => array:2 [
        "dt" => "2020-11-15"
        "orders" => 1
      ]
      8 => array:2 [
        "dt" => "2020-11-17"
        "orders" => 3
      ]
      9 => array:2 [
        "dt" => "2020-11-19"
        "orders" => 4
      ]
    ]

I need to group it by date (more specifically the ‘dt’ field), so that the data is like as follows:


    "dt" => "2020-11-18"
    "cupoms" => 9
    "visits"=> 48
    
    "dt" => "2020-11-19"
    "cupoms" => 1
    "visits" => 3
    "orders" => 4
    
    "dt" => "2020-11-14"
    "visits"=> 1

I tried a few loops, but to no avail

Advertisement

Answer

Update: I edited the answer because I realized that it wasn’t adding the numerical values together, it was just taking the first value; The code got a bit more complicated but there is no straightforward way to do it with collections, I’d sill recommend using collections instead of loops of arrays


With laravel you can take advantage of collections, they are very powerfull, here is a working example:

        $array = [
      [
        "dt" => "2020-11-18",
        "cupoms" => 9
      ],
      [
        "dt" => "2020-11-19",
        "cupoms" => 1
      ],
      [
        "dt"=> "2020-11-14",
        "visits"=> 1
      ],
      [
        "dt"=> "2020-11-15",
        "visits"=> 1
      ],
      [
        "dt"=> "2020-11-16",
        "visits"=> 9
      ],
      [
        "dt"=> "2020-11-18",
        "visits"=> 48
      ],
      [
        "dt"=> "2020-11-19",
        "visits"=> 3
      ],
      [
        "dt" => "2020-11-15",
        "orders" => 1
      ],
      [
        "dt" => "2020-11-17",
        "orders" => 3
      ],
      [
        "dt" => "2020-11-19",
        "orders" => 4
      ]
    ];

    $collection = collect($array);

    $grouped = $collection->groupBy('dt');

    //up to this step($merged_rec) you already preserved and grouped all the values 
    //and you can sum the values manually if you wish, 
    //but in the next step I will suggest a solution using collections
    $merged_rec = $grouped->map(function ($items) {
        return collect($items)->reduce(function ($carry, $item) {
            return collect($carry)->mergeRecursive($item);
        }, collect([]));
    });
    
    //this will reduce the numeric arrays to a single value (sum) 
    //using collections
    $summed = $merged_rec->map(function ($items){
        return collect($items->map(function($subitems) {
            if( is_array($subitems) && count($subitems) > 0 && is_numeric($subitems[0]) ){
                return collect($subitems)->sum();
            } else {
                return $subitems;
            }
        }));
    });

    print_r($summed->toArray());

this will output:

    array:6 [
      "2020-11-18" => array:3 [
        "dt" => array:2 [
          0 => "2020-11-18"
          1 => "2020-11-18"
        ]
        "cupoms" => 9
        "visits" => 48
      ]
      "2020-11-19" => array:3 [
        "dt" => array:3 [
          0 => "2020-11-19"
          1 => "2020-11-19"
          2 => "2020-11-19"
        ]
        "cupoms" => 1
        "visits" => 3
      ]
      "2020-11-14" => array:2 [
        "dt" => "2020-11-14"
        "visits" => 1
      ]
      "2020-11-15" => array:3 [
        "dt" => array:2 [
          0 => "2020-11-15"
          1 => "2020-11-15"
        ]
        "visits" => 1
        "orders" => 1
      ]
      "2020-11-16" => array:2 [
        "dt" => "2020-11-16"
        "visits" => 9
      ]
      "2020-11-17" => array:2 [
        "dt" => "2020-11-17"
        "orders" => 3
      ]
    ]

Read more: https://laravel.com/docs/8.x/collections#method-groupby

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement