Как объединить два массива и суммировать значения дубликатов ключей?

Я хотел бы объединить массив по условиям. Если ключи массива совпадают, добавьте значения, если нет, сохраните значение.

Вот мои массивы:

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

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

Мой желаемый результат:

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

Я использовал условия if-else, но он повторяет значение, которое уже соответствует.

Вот моя попытка кодирования:

$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);
        }
    }
}   

3 ответа

Решение

Я думаю, что проблема проще, чем кажется. Вам действительно нужно только условие, чтобы исключить неопределенные уведомления о смещениях. Просто итерируйте все ключи и значения в обоих массивах и добавьте значения к соответствующему ключу в объединенном массиве.

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
    }
}

Действительно, строка, которая на самом деле делает сложение ($merged[$key] = $value + ($merged[$key] ?? 0);) может быть уменьшен до $merged[$key] += $value;, Это все еще будет работать, но это будет производить кучу неопределенных уведомлений о смещениях. Таким образом, вместо этого мы можем установить ключ равным значению плюс либо предыдущее значение (если оно существует), либо ноль.

Если вы все еще используете PHP 5, вы можете использовать троичный вместо оператора объединения нулей (??), как это:

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

Вывод не будет в том же порядке, как показано в желаемом результате, но вы можете использовать ksort($merged); выполнить это, как указано в принятом ответе.

Сначала вы можете объединить массивы, объединив все значения в одном ключе:

$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];
    }
}

Это приведет к:

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

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

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

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

)

Затем вы можете отобразить их в соответствии с вашими условиями:

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

Результат:

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

Если вы хотите, чтобы ключи были отсортированы, вы можете запустить их через ksort также

Проверьте код:

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

Вы можете достичь этого путем

$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;
    }
}
Другие вопросы по тегам