Search code examples
phparraysmultidimensional-arraysumgrouping

How to iterate multidimensional array data and sum some values ​to return a grouped array


What's the simplest way and uses less computing power to check if a multidimensional array has some equal values in the sub keys and, if is in this way, make the sum of that?

Look at the input. It's something like this:

$array[] = ['number' => 1, 'values' => ['a' => 1, 'b' => 2]];
$array[] = ['number' => 2, 'values' => ['a' => 4, 'b' => 1]];
$array[] = ['number' => 2, 'values' => ['a' => 1, 'b' => 4]]; // same "number" as the previous so get the sum between "a" of the previous and "a" of this, the same for "b"
$array[] = ['number' => 2, 'values' => ['a' => 1, 'b' => 1]]; // same "number" as the previous so get the sum between "a" of the previous and "a" of this, the same for "b"
$array[] = ['number' => 3, 'values' => ['a' => 2, 'b' => 4]];

So the output should be

$array[0] : ['number' => 1, 'values' => ['a' => 1, 'b' => 2]];
$array[1] : ['number' => 2, 'values' => ['a' => 6, 'b' => 6]]; //a = 4 + 1 + 1     //b = 1 + 4 + 1
$array[2] : ['number' => 3, 'values' => ['a' => 2, 'b' => 4]];

To tell the truth I have trouble doing it even with simple foreach.

My brain can only go so far and no further.

$array_output = [];
foreach ($array as $k => $v){
    foreach ($array as $kk => $vv){
        if ($v['number'] == $vv['number']) {
            // ????
        }
    }
}

Anyone help me?


Another question in the same question

How to do the same thing for
$array[] = ['number' => 1, 'a' => 1, 'b' => 2];
$array[] = ['number' => 2, 'a' => 4, 'b' => 1];
$array[] = ['number' => 2, 'a' => 1, 'b' => 4];
$array[] = ['number' => 2, 'a' => 1, 'b' => 1];
$array[] = ['number' => 3, 'a' => 2, 'b' => 4];

so how to get the sum for same variable number for a and b variables?


Solution

  • $seen = [];
    $i = 0;
    foreach ($array as $data) {
        $number = $data['number'];
        $a = $data['values']['a'];
        $b = $data['values']['b'];
    
        if (isset($seen[$number])) {
            $output[$seen[$number]]['values']['a'] += $a;
            $output[$seen[$number]]['values']['b'] += $b;
        } else {
            $output[] = $data;
            $seen[$number] = $i;
            $i++;
        }
        //$i++;
    }
    

    checking result

    print_r($output);
    

    gives me this

    Array ( [0] => Array ( [number] => 1 [values] => Array ( [a] => 1 [b] => 2 ) ) [1] => Array ( [number] => 2 [values] => Array ( [a] => 6 [b] => 6 ) ) [2] => Array ( [number] => 3 [values] => Array ( [a] => 2 [b] => 4 ) ) )
    

    edit: went back and saw C.H's comment about a wrong increment placement, code now corrected.

    Just to add, to answer the follow up question you can remove all mentions of ['values'] to use the same logic for the simpler second array example.