Search code examples
phparraysmergesumunique

Merge two 2d arrays grouping on one column value and summing another column value within each group


Basically I need to take two arrays, merge them with unique values and sum one of columns. It makes more sense when written out below:

$a = [
    ['ID' => 1, 'Count' => 2],
];

$b = [
    ['ID' => 1, 'Count' => 4],
    ['ID' => 2, 'Count' => 3]
];

and I need the final product to be:

$a_plus_b = [
    ['ID' => 1, 'Count' => 6],
    ['ID' => 2, 'Count' => 3]
];

I have been playing with different variations of array_merge() and array_unique(), but I can't find an efficient way to do what I need. I know I can always do nested loops, but I was hoping for something easier. Any ideas?


Solution

  • This should do the trick

    Note: This solution requires PHP >= 5.3. There is a PHP < 5.3 solution below.

    $input = array($a, $b);
    // add as many result arrays to $input as you want; e.g.,
    // $input = array($a, $b, $c, $d);
    
    $output = array_count_values(
      call_user_func_array(
        'array_merge',
         array_map(
           function($arr) {
             return array_fill(0, $arr['Count'], $arr['ID']);
           },
           call_user_func_array(
             'array_merge',
             $input
           )
         )
      )
    );
    
    print_r($output);
    

    Output

    Array
    (
        [1] => 6
        [2] => 3
    )
    

    Note the array keys above are ID values. The array values are Count values.


    If you're running PHP < 5.2 you won't be able to use the inline closure with array_fill. You have to define it as a separate function.

    $input = array($a, $b);
    
    function _fill($arr) {
      return array_fill(0, $arr['Count'], $arr['ID']);
    }
    
    $output = array_count_values(
      call_user_func_array(
        'array_merge',
        array_map(
          '_fill',
          call_user_func_array(
            'array_merge',
            $input
          )
        )
      )
    );
    
    print_r($output);
    

    From here, converting the output to your desired format is a trivial task.