How to merge two arrays and sum the values ​​of duplicate keys?

advertisements

I would like to merge array by conditions. If array keys match then add the values, if not then retain the value.

Here are my arrays:

Array1
(
    [1] => 199
    [3] => 1306
    [5] => 199
)

Array2
(
   [3] => 199
   [4] => 199
)

My desired result is:

Result
(
   [1] => 199
   [3] => 1505
   [4] => 199
   [5] => 199
)

I used if-else conditions, but it's repeating the value which is already matched.

Here is my coding attempt:

$all=array();
foreach($sall as $sskey => $ssvalue){
    foreach($upgradesall as $uukey => $uuvalue){
        //$sskey==$uukey?$all[] = array("id"=>$sskey, "amount"=>$ssvalue+$uuvalue):($sskey!=$uukey? $all[] = array("id"=>$sskey, "amount"=>$ssvalue):($uukey!=$sskey?$all[] = array("id"=>$uukey, "amount"=>$uuvalue):''));
        if($sskey===$uukey){
            $all[] = array("id"=>$sskey, "amount"=>$ssvalue+$uuvalue);
        }elseif($sskey!=$uukey){
            $all[] = array("id"=>$sskey, "amount"=>$ssvalue);
        }elseif($uukey!=$sskey){
            $all[] = array("id"=>$uukey, "amount"=>$uuvalue);
        }
    }
}


I think the problem is simpler than it looks. You really only need a conditional to preclude undefined offset notices. Just iterate all keys and values in both arrays and add the values to the corresponding key in the merged array.

foreach ([$a1, $a2] as $a) {                             // iterate both arrays
    foreach ($a as $key => $value) {                     // iterate all keys+values
        $merged[$key] = $value + ($merged[$key] ?? 0);   // merge and add
    }
}

Really, the line that actually does the addition ($merged[$key] = $value + ($merged[$key] ?? 0);) could be reduced to $merged[$key] += $value;. That would still work, but it would produce a bunch of undefined offset notices. So instead we can set the key equal to the value plus either the previous value (if it exists) or zero.

If you're still using PHP 5, you can use a ternary instead of the null coalescing operator (??), like this:

$merged[$key] = $value + (isset($merged[$key]) ? $merged[$key] : 0);

The output won't be in the same order shown in your desired result, but you can use ksort($merged); to accomplish that as stated in the accepted answer.