web-dev-qa-db-ja.com

マージされた値を合計して2つの配列をマージする方法

重複の可能性:
PHP:同じキーの配列の値を合計する方法

値を置き換えないarray_merge()関数を探していますが、値をADDSしています。

例、これは私が試しているコードです:

    echo "<pre>"; 

    $a1 = array(
         "a" => 2
        ,"b" => 0
        ,"c" => 5
    );

    $a2 = array(
         "a" => 3
        ,"b" => 9
        ,"c" => 7
        ,"d" => 10
    );

    $a3 = array_merge($a1, $a2);
    print_r($a3); 

悲しいことに、これはこれを出力します:

Array
(
    [a] => 3
    [b] => 9
    [c] => 7
    [d] => 10
)

次に、array_mergeの代わりに、2つの配列を追加するだけで試してみました

$a3 = $a1 + $a2;

しかし、これは出力

Array
(
    [a] => 2
    [b] => 0
    [c] => 5
    [d] => 10
)

私が本当に欲しいのは、必要なだけ多くの配列を渡して、それらの合計を取得できることです。だから私の例では、出力を次のようにしたい:

Array
(
    [a] => 5
    [b] => 9
    [c] => 12
    [d] => 10
)

もちろん、多くのforeachなどを使用して一部の関数をシュレップして構築することはできますが、見栄えがするか、よりスマートでクリーンなソリューションです。ポインタをありがとう!

29
Erick
$sums = array();
foreach (array_keys($a1 + $a2) as $key) {
    $sums[$key] = (isset($a1[$key]) ? $a1[$key] : 0) + (isset($a2[$key]) ? $a2[$key] : 0);
}

couldエラー抑制演算子を使用してこれを次のように短くしますが、見苦しいと考える必要があります。

$sums = array();
foreach (array_keys($a1 + $a2) as $key) {
    $sums[$key] = @($a1[$key] + $a2[$key]);
}

または、いくつかのマッピング:

$keys = array_fill_keys(array_keys($a1 + $a2), 0);
$sums = array_map(function ($a1, $a2) { return $a1 + $a2; }, array_merge($keys, $a1), array_merge($keys, $a2));

または、両方のソリューションの組み合わせのようなものです:

$sums = array_fill_keys(array_keys($a1 + $a2), 0);
array_walk($sums, function (&$value, $key, $arrs) { $value = @($arrs[0][$key] + $arrs[1][$key]); }, array($a1, $a2));

これらは必要に応じてそれらの1つをその場で適応させるのに十分簡潔ですが、無制限の数の配列を受け入れてそれらを合計する関数の観点から言えば、次のようになります。

function array_sum_identical_keys() {
    $arrays = func_get_args();
    $keys = array_keys(array_reduce($arrays, function ($keys, $arr) { return $keys + $arr; }, array()));
    $sums = array();

    foreach ($keys as $key) {
        $sums[$key] = array_reduce($arrays, function ($sum, $arr) use ($key) { return $sum + @$arr[$key]; });
    }
    return $sums;
}
57
deceze

私の貢献:

function array_merge_numeric_values()
{
    $arrays = func_get_args();
    $merged = array();
    foreach ($arrays as $array)
    {
        foreach ($array as $key => $value)
        {
            if ( ! is_numeric($value))
            {
                continue;
            }
            if ( ! isset($merged[$key]))
            {
                $merged[$key] = $value;
            }
            else
            {
                $merged[$key] += $value;
            }
        }
    }
    return $merged;
}

必要なだけ配列を渡します。いくつかの防御、多次元配列を受け入れる機能、または型チェックを自由に追加してください。

デモ: http://codepad.org/JG6zwAap

13
Wesley Murch

それほど複雑ではありません:

$a3 = $a1;

foreach($a2 as $k => $v) {
    if(array_key_exists($k, $a3)) {
       $a3[$k] += $v;
    } else {
       $a3[$k] = $v; 
    }
}
3
Haim Evgi