Search code examples
phparraysmultidimensional-arraypivotgrouping

Pivot data in an array of associative arrays to group by values in one column


I have a large multidimensional array structured like the sample below.

[
    ['name' => 'SMITH', 'status' => 'Incomplete', 'count' => 2],
    ['name' => 'SMITH', 'status' => 'Complete', 'count' => 2],
    ['name' => 'HUGHES', 'status' => 'Incomplete', 'count' => 3],
    ['name' => 'HUGHES', 'status' => 'Complete', 'count' => 1],
];

What I would like is a new array that looks like this -

[
    ['name' => 'SMITH', 'Incomplete' => 2, 'Complete' => 2],
    ['name' => 'HUGHES', 'Incomplete' => 3, 'Complete' => 1]
]

I'm pretty new to PHP and I do realize I need to loop through the original array but any help would be appreciated.


Solution

  • $original = array( array ( 'name' => 'SMITH',
                               'status' => 'Incomplete',
                               'count' => 2
                             ),
                       array ( 'name' => 'SMITH',
                               'status' => 'Complete',
                               'count' => 2
                             ),
    
                       array ( 'name' => 'HUGHES',
                               'status' => 'Incomplete',
                               'count' => 3
                             ),
                       array ( 'name' => 'HUGHES',
                               'status' => 'Complete',
                               'count' => 1
                             ),
                     );
    
    // initialise our new array
    $newArray = array();
    // loop through each entry from the original array in turn
    foreach($original as $entry) {
        // temporarily use the name as the key for our new array (we'll reset to a numeric later)
        $name = $entry['name'];
        $newArray[$name]['name'] = $name;
        //  test if we have multiple entries for the same name/status
        if (isset($newArray[$name][$entry['status']])) {
            $newArray[$name][$entry['status']] += $entry['count'];
        } else {
            $newArray[$name][$entry['status']] = $entry['count'];
        }
    }
    
    //  Reset top-level keys to numerics
    $newArray = array_values($newArray);
    
    echo '<pre>';
    var_dump($newArray);
    echo '</pre>';