web-dev-qa-db-fra.com

Comment fusionner deux tableaux en additionnant les valeurs fusionnées

Duplicata possible:
PHP: comment additionner les valeurs du tableau de la même clé

Je recherche une fonction array_merge() qui ne remplace PAS les valeurs, mais les AJOUTE.

Exemple, voici le code que j'essaie:

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

Malheureusement, cela produit ceci:

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

J'ai ensuite essayé, au lieu de array_merge, en ajoutant simplement les deux tableaux

$a3 = $a1 + $a2;

Mais cela produit

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

Ce que je veux vraiment, c'est pouvoir passer autant de tableaux que nécessaire, puis obtenir leur somme. Donc, dans mon exemple, je veux que la sortie soit:

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

Bien sûr, je peux schlepp et construire une fonction avec de nombreux foreach etc, mais je cherche ou une solution plus intelligente et plus propre. Merci pour tous les conseils!

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

Vous pourriez raccourcir ceci en utilisant l'opérateur de suppression d'erreur, mais cela devrait être considéré comme laid:

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

Alternativement, une cartographie:

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

Ou une sorte de combinaison des deux solutions:

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

Je pense que ceux-ci sont suffisamment concis pour adapter l'un d'eux sur place chaque fois que cela est nécessaire, mais pour le dire en termes de fonction qui accepte un nombre illimité de tableaux et les résume:

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

Ma contribution:

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

Passez autant de tableaux que vous le souhaitez. N'hésitez pas à ajouter un peu plus de défense, à accepter des tableaux multidimensionnels ou à vérifier les types.

Démo: http://codepad.org/JG6zwAap

13
Wesley Murch

ce n'est pas si compliqué faire quelque chose comme:

$a3 = $a1;

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