Search code examples
phparraysmultidimensional-arraygroupingreduce

Merge deep groups of rows by their numeric key and sum column values while grouping


I have the following array which needs to be reduced with internal values being summed.

Input:

$array = [
    [
        121 => [ "number" => 121, "name" => "Some Name 1", "value" => "2.222" ],
        116 => [ "number" => 116, "name" => "Some Name 2", "value" => "1.111" ],
          1 => [ "number" =>   1, "name" => "Some Name 3", "value" => "1.232" ]
    ],
    [
        121 => [ "number" => 121, "name" => "Some Name 1", "value" => "1.111" ],
        116 => [ "number" => 116, "name" => "Some Name 2", "value" => "2.222" ],
          1 => [ "number" =>   1, "name" => "Some Name 3", "value" => "3.111" ]
    ]
];

Desired result:

0 => array:116 [
  121 => array:3 [
    "number" => 121
    "name" => "Some Name 1"
    "value" => "3.333"
  ] 
  116 => array:3 [
    "number" => 116
    "name" => "Some Name 2"
    "value" => "3.333"
  ]
  1 => array:3 [
    "number" => 1
    "name" => "Some Name 3"
    "value" => "4.343"
  ]
]

What would be the efficient/effective way to calculate the resulting array based on the input, assuming that the length of input array is undefined, but the complexity/nesting level is 2 maximum.

I am seeking a performance optimized solution for PHP5.6 as well as PHP7+.


Solution

  • Use nested loops to access your deep subarrays. As you iterate push first-encountered rows into the result array while preserving their numeric/associative key. Use these keys to determine (while looping) to determine if a row has been encountered before -- if so, merely add the value value to the cached row.

    Code: (Demo)

    $result = [];
    foreach ($array as $group) {
        foreach ($group as $key => $row) {
            if (!isset($result[$key])) {
                $result[$key] = $row;
            } else {
                $result[$key]['value'] += $row['value'];
            }
        }
    }
    var_export($result);