3

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);
        }
    }
}   
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
SAHAR
  • 49
  • 1
  • 8

3 Answers3

6

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

Don't Panic
  • 41,125
  • 10
  • 61
  • 80
2

First you can merge the arrays by merging all values in the same key:

$allKeys = array_unique(array_merge(array_keys($arr1),array_keys($arr2)));
$result = [];
foreach ($allKeys as $key) {
    $result[$key] = [];
    if (array_key_exists($key,$arr1)) {
        $result[$key][] = $arr1[$key];
    }
    if (array_key_exists($key,$arr2)) {
        $result[$key][] = $arr2[$key];
    }
}

This will result in:

Array
(
    [1] => Array
        (
            [0] => 199
        )

    [3] => Array
        (
            [0] => 1306
            [1] => 199
        )

    [5] => Array
        (
            [0] => 199
        )

    [4] => Array
        (
            [0] => 199
        )

)

Then you can map them according to your conditions:

$endResult = array_map('array_sum',$result);

Result:

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

If you want the keys to be sorted you can run them through a ksort as well

Check the code:

http://sandbox.onlinephpfunctions.com/code/3eb23310f0fd8de8174a5caf8b2b91d4b7562b6b

apokryfos
  • 38,771
  • 9
  • 70
  • 114
  • I'm getting problem in some conditions and not getting the desired result. http://sandbox.onlinephpfunctions.com/code/f0c876f693d1dee53ac2afc8d7d102106eb92025 – SAHAR Jul 01 '17 at 05:31
-1

You could achieve that by

$all = array_merge($arr1,$arr2); // existing elements in arr1 are replaced by arr2 else merge into new array_merge
//then add replaced elememnts value
foreach($arr1 as $k=>$v)
{
    if(array_key_exists($k,$all))
    {
        $all[$k] = $all[$k] + $v;
    }
}
sathish R
  • 402
  • 4
  • 8
  • Will give Array ( [0] => 199 [1] => 1505 [2] => 199 [3] => 1505 [4] => 199 ) – sumit Jun 30 '17 at 05:46
  • is your array associative or index array?. this code works for associative array – sathish R Jun 30 '17 at 05:48
  • No, as you have used array_merge so the index wont be preserved – sumit Jun 30 '17 at 05:52
  • If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended. Values in the input array with numeric keys will be renumbered with incrementing keys starting from zero in the result array. – sathish R Jun 30 '17 at 05:55
  • Thanks [Satish R](https://stackoverflow.com/users/4160999/sathish-r) for your solutions. My array has unique Ids and in this script we are loosing them. I got the solution by [Don't Panic](https://stackoverflow.com/users/2734189/dont-panic) and its working as I expected. – SAHAR Jul 01 '17 at 07:44