Search code examples
phparraysmultidimensional-arraysumgrouping

Group 2d array data by 2 columns to form a 3d associative array with summed column values in each group


I have a 2d array with this data:

[
    [
        "totalTonne" => 11180,
        "wasteHierarchy" => "Disposal (Landfill)",
        "completionDate" => "2014-05-14"
    ],
    [
        "totalTonne" => 820,
        "wasteHierarchy" => "Energy Recovery",
        "completionDate" => "2014-06-14"
    ],
    [
        "totalTonne" => 21040,
        "wasteHierarchy" => "Energy Recovery",
        "completionDate" => "2014-08-14"
    ],
    [
        "totalTonne" => 7020,
        "wasteHierarchy" => "Energy Recovery",
        "completionDate" => "2014-11-14"
    ],
    [
        "totalTonne" => 6660,
        "wasteHierarchy" => "Recycling",
        "completionDate" => "2014-07-14"
    ],
    [
        "totalTonne" => 12000,
        "wasteHierarchy" => "Recycling",
        "completionDate" => "2014-09-14"
    ],
    [
        "totalTonne" => 8900,
        "wasteHierarchy" => "Recycling",
        "completionDate" => "2014-10-14"
    ],
    [
        "totalTonne" => 9100,
        "wasteHierarchy" => "Recycling",
        "completionDate" => "2014-12-14"
    ],
    [
        "totalTonne" => 5520,
        "wasteHierarchy" => "Recycling",
        "completionDate" => "2015-01-15"
    ],
    [
        "totalTonne" => 1900,
        "wasteHierarchy" => "Energy Recovery",
        "completionDate" => "2014-08-14"
    ],
    [
        "totalTonne" => 5950,
        "wasteHierarchy" => "Energy Recovery",
        "completionDate" => "2014-11-14"
    ],
    [
        "totalTonne" => 12000,
        "wasteHierarchy" => "Recycling",
        "completionDate" => "2014-07-14"
    ],
    [
        "totalTonne" => 10480,
        "wasteHierarchy" => "Recycling",
        "completionDate" => "2014-09-14"
    ],
    [
        "totalTonne" => 8900,
        "wasteHierarchy" => "Recycling",
        "completionDate" => "2014-10-14"
    ],
    [
        "totalTonne" => 10060,
        "wasteHierarchy" => "Recycling",
        "completionDate" => "2014-12-14"
    ],
    [
        "totalTonne" => 15500,
        "wasteHierarchy" => "Energy Recovery",
        "completionDate" => "2014-06-14"
    ],
    [
        "totalTonne" => 8850,
        "wasteHierarchy" => "Energy Recovery",
        "completionDate" => "2014-11-14"
    ]
]

I would like to convert it to a 3d array which groups by wasteHierarchy values on the first level, then completionDate values on the second level and then sums the totalTonne values in each group.

Desired output:

[Disposal (Landfill)] => Array
    (
        [May 14] => 11180
    )

[Energy Recovery] => Array
    (
        [Jun 14] => 16320
        [Aug 14] => 22940
        [Nov 14] => 21820
    )

[Recycling] => Array
    (
        [Jul 14] => 18660
        [Sep 14] => 22480
        [Oct 14] => 17800
        [Dec 14] => 19160
        [Jan 15] => 5520
    )

The PHP code I have, so far, is below:

$whmOutput = Array();
foreach($wasteHierMon as $whm) {
    $dateChanged = date("M y", strtotime($whm['completionDate']));

    $whmOutput_element = &$whmOutput[$dateChanged];
    $whmOutput_element['wasteHierarchy'] = $whm['wasteHierarchy'];
    $whmOutput_element['completionDate'] = $dateChanged;
    !isset($whmOutput_element['totalUom']) && $whmOutput_element['totalUom'] = 0;
    $whmOutput_element['totalUom'] += $whm['totalTonne'];

}
$newWHM = array();          
foreach($whmOutput as $whm) {
    $dateChanged = $whm['completionDate'];

    $wasteHierarchy = $whm['wasteHierarchy'];
    $totalUom = +$whm['totalUom'];

    $newWHM[$wasteHierarchy][$dateChanged] = $totalUom;
}

However, that code doesn't do the job properly. While it creates the structure I'm after, but it doesn't rearrange the data properly. It doesn't group the dates correctly and, because of this, the totalTonne value with that isn't correct.

How can I amend the code in order to achieve this?


Solution

  • Something like this should work: Demo

    $whmOutput = array();
    foreach ($wasteHierMon as $whm) {
        $dateChanged = date("M y", strtotime($whm['completionDate']));
         // if not defined, define with value zero
        if (!isset($whmOutput[$whm['wasteHierarchy']][$dateChanged])) {
            $whmOutput[$whm['wasteHierarchy']][$dateChanged] = 0;
        }
        // addition will always work now
        $whmOutput[$whm['wasteHierarchy']][$dateChanged] += $whm['totalTonne'];
    }