Search code examples
phparraysarray-merge

Merge arrays with Sum specific value keys


If someone has already done it, the idea is to merge different arrays into one and also merge the values sum of price, qty only for the identical keys.

In my example I only put two arrays to be merged $arr1, $arr2 but the idea is to do it dynamically because I do not have a defined number of arrays , I can have 2 as I can have 15.

Example:

<?php

$arr1 = [
    51 => [
        'name' => 'p1',
        'price' => '20',
        'qty' => '10',
        'category' => 'c1'
    ],
    
    3 => [
        'name' => 'p2',
        'price' => '10.50',
        'qty' => '3',
        'category' => 'c2'
    ]
];
    
$arr2 = [
    3 => [
        'name' => 'p3',
        'price' => '23',
        'qty' => '22',
        'category' => 'c1'
    ],
    
    102 => [
        'name' => 'p4',
        'price' => '10.50',
        'qty' => '8',
        'category' => 'c2'
    ]
    
];

Code :

mergeArrays(($arr1 + $arr2));



function mergeArrays($array)
{
    $mergedArray = [];
    foreach ($array as $k => $arr) {
        foreach ($arr as $key => $value) {
            if (!isset($mergedArray[$key])) {
                $mergedArray[$k][$key] = $value;
            } else {
                $mergedArray[$key] += $value;
            }
        }
    }
    print_r($mergedArray);
    //return $mergedArray;
}

Result:

Array
(
    [51] => Array
        (
            [name] => p1
            [price] => 20
            [qty] => 10
            [category] => c1
        )

    [3] => Array
        (
            [name] => p2
            [price] => 10.50
            [qty] => 3
            [category] => c2
        )

    [102] => Array
        (
            [name] => p4
            [price] => 10.50
            [qty] => 8
            [category] => c2
        )

)

Expected result:

Array
(
    [51] => Array
        (
            [name] => p1
            [price] => 20
            [qty] => 10
            [category] => c1
        )

    [3] => Array
        (
            [name] => p3       // the last erray value
            [price] => 33.50   //sum
            [qty] => 25        //sum
            [category] => c1   // the last erray value
        )

    [102] => Array
        (
            [name] => p4
            [price] => 10.50
            [qty] => 8
            [category] => c2
        )

)


Solution

  • Using the ...$in to indicate any number of arrays can be passed to the function and then a couple of loops will do the job for you

    $arr1 = [  51 => [  'name' => 'p1', 'price' => '20', 'qty' => '10', 'category' => 'c1' ],
                3 => [  'name' => 'p2', 'price' => '10.50', 'qty' => '3',  'category' => 'c2' ]
        ];
        
    $arr2 = [  3 => [ 'name' => 'p3',  'price' => '23', 'qty' => '22', 'category' => 'c1'  ],
             102 => [ 'name' => 'p4',  'price' => '10.50', 'qty' => '8', 'category' => 'c2' ]
        ];
    
    function myMerge(Array ...$in)
    {
        $new = $in[0];
    
        for($i=1; $i<count($in); $i++){
            foreach($in[$i] as $idx => &$a) {
                if( isset($new[$idx]) ){
                    $new[$idx]['qty'] += $a['qty'];
                    $new[$idx]['price'] += $a['price'];
                } else {
                    $new[$idx] = $a;
                }
            }
        }        
        return $new;
    }
    
    print_r( myMerge($arr1, $arr2) );
    

    RESULT

    Array
    (
        [51] => Array
            (
                [name] => p1
                [price] => 20
                [qty] => 10
                [category] => c1
            )
    
        [3] => Array
            (
                [name] => p2
                [price] => 33.5
                [qty] => 25
                [category] => c2
            )
    
        [102] => Array
            (
                [name] => p4
                [price] => 10.50
                [qty] => 8
                [category] => c2
            )
    
    )