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

473

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+.

58

Answer

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 thevalue 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);
2

Answer

Solution:

I updated the functionality to be able to take many children. In the repl I've linked two I added an extra child to both array key's 0 and 1.

// Merege $a[0] and $a[1] and sum up the `value` key 

$merge_sum = array_map(function($key, ...$a) {
  $merged = array_merge(...$a);
  $merged['value'] = array_sum(array_column($a, 'value'));
  return [ $key => $merged ];
}, array_keys($a[0]), ...$a);

// // Fix array array keys

$final = array_reduce($merge_sum, function($c, $i) {
  $concat = $c + $i;
  return $concat;
}, []);

var_dump($final);

Test it on this repl; https://repl.it/Id7T/6

People are also looking for solutions to the problem: php - how to delete row items and fadeout in ajax jquery

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.