Search code examples
phparraysmultidimensional-arraysumgrouping

Merge and sum related subsets in a multidimensional array


I have a multidimensional array containing a set of data for sales and a set of data for rd_sales. I need to merge and sum the related values between these two data sets.

[
    'sales' => [
        'brand'=> [
            3 => [
                'total_qty'=> 12.000,
                'total_amt'=> 336000.00
            ],
            4 => [
                'total_qty'=> 1.240,
                'total_amt'=> 24800.00
            ],
        ],
        'sales_value' => 360800
    ],
    'rdsales' => [
        'brand'=> [
            1 => [
                'total_qty'=> 3.000,
                'total_amt'=> 91500.00
            ],
            3 => [
                'total_qty'=> 0.020,
                'total_amt'=> 600.000
            ],
            4 => [
                'total_qty'=> 5.000,
                'total_amt'=> 100000.00
            ],
        ],
        'sales_value' => 192100
    ],    
]

In the above sample, the brand data in 1 of sales is not found in the brand data of rd_sales, so it merely needs to be transferred to the result.

As for 3 and 4, these data sets are represented in both sets -- the corresponding values need to be summed and stored in the result array.

enter image description here

Desired result:

array (
  'sum_rdsales_sales' => 
  array (
    'brand' => 
    array (
      1 => 
      array (
        'total_qty' => 3.0,
        'total_amt' => 91500.0,
      ),
      3 => 
      array (
        'total_qty' => 12.02,
        'total_amt' => 336600.0,
      ),
      4 => 
      array (
        'total_qty' => 6.24,
        'total_amt' => 124800.0,
      ),
    ),
    'sales_value' => 552900,
  ),
)

Solution

  • Use the following approach(used functions: array_sum, array_column):

    $arr = [
        'sales' => ['brand'=> [
            3 => ['total_qty'=> 12.000, 'total_amt'=> 336000.00],
            4 => ['total_qty'=> 1.240, 'total_amt'=> 24800.00],
            ], 'sales_value' => 360800],
        'rdsales' => ['brand'=> [
            1 => ['total_qty'=> 3.000, 'total_amt'=> 91500.00],
            3 => ['total_qty'=> 0.020, 'total_amt'=> 600.000],
            4 => ['total_qty'=> 5.000, 'total_amt'=> 100000.00],
            ], 'sales_value' => 192100],    
    ];
    
    $result = [];
    $result['sum_rdsales_sales'] = [
        'brand' => [],
        'sales_value' => array_sum(array_column($arr, 'sales_value'))];
    
    // `$prevalent_arr` is the array which has larger amount of elements
    if ((count($arr['sales']['brand']) > count($arr['rdsales']['brand']))) {
        $prevalent_arr = $arr['sales']['brand'];
        $compared_arr = $arr['rdsales']['brand'];
    } else {
        $prevalent_arr = $arr['rdsales']['brand'];
        $compared_arr = $arr['sales']['brand'];
    }
    
    foreach ($prevalent_arr as $k => $v) {
        if (isset($compared_arr[$k])) {        
            $result['sum_rdsales_sales']['brand'][$k]['total_qty'] = $prevalent_arr[$k]['total_qty'] + $compared_arr[$k]['total_qty'];
            $result['sum_rdsales_sales']['brand'][$k]['total_amt'] = $prevalent_arr[$k]['total_amt'] + $compared_arr[$k]['total_amt'];
        } else {
            $result['sum_rdsales_sales']['brand'][$k] = $prevalent_arr[$k];
        }
    }
    
    print_r($result);
    

    The output:

    Array
    (
        [sum_rdsales_sales] => Array
            (
                [brand] => Array
                    (
                        [1] => Array
                            (
                                [total_qty] => 3
                                [total_amt] => 91500
                            )
    
                        [3] => Array
                            (
                                [total_qty] => 12.02
                                [total_amt] => 336600
                            )
    
                        [4] => Array
                            (
                                [total_qty] => 6.24
                                [total_amt] => 124800
                            )
    
                    )
    
                [sales_value] => 552900
            )
    )