129 votes

Comment additionner les valeurs de toutes les colonnes d'un tableau multidimensionnel ?

Comment puis-je ajouter toutes les valeurs en colonne par clé associative ? Notez que les jeux de clés sont dynamiques.

Tableau d'entrée :

Array
(
    [0] => Array
        (
            [gozhi] => 2
            [uzorong] => 1
            [ngangla] => 4
            [langthel] => 5
        )

    [1] => Array
        (
            [gozhi] => 5
            [uzorong] => 0
            [ngangla] => 3
            [langthel] => 2
        )

    [2] => Array
        (
            [gozhi] => 3
            [uzorong] => 0
            [ngangla] => 1
            [langthel] => 3
        )
)

Résultat souhaité :

Array
(
    [gozhi] => 10
    [uzorong] => 1
    [ngangla] => 8
    [langthel] => 10
)

0 votes

Dans une situation courante, deux tableaux multidimensionnels n'ont pas exactement les mêmes clés. fusion/somme d'un tableau multidimensionnel php

98voto

Chris J Points 2581
$sumArray = array();

foreach ($myArray as $k=>$subArray) {
  foreach ($subArray as $id=>$value) {
    $sumArray[$id]+=$value;
  }
}

print_r($sumArray);

55 votes

Cela lancera des avis pour la première itération car les clés n'existent pas encore.

3 votes

Array_reduce me semble le plus joli. stackoverflow.com/questions/14195916/

13 votes

Pour éviter les avis, vous pouvez remplacer la ligne qui assigne les valeurs au tableau $sumArray par : array_key_exists( $id, $sumArray ) ? $sumArray[$id] += $value : $sumArray[$id] = $value ;

28voto

Gumbo Points 279147

Voici une solution similaire aux deux autres :

$acc = array_shift($arr);
foreach ($arr as $val) {
    foreach ($val as $key => $val) {
        $acc[$key] += $val;
    }
}

Mais ceci n'a pas besoin de vérifier si les clés du tableau existent déjà et ne jette pas d'avis non plus.

0 votes

+1 solution très intelligente pour cette structure de tableau spécifique. Dommage qu'elle ne fonctionne pas dans le cas plus général de tableaux tous structurés comme le résultat final.

22voto

npcoda Points 182

On peut aussi le faire en utilisant array_map :

$rArray = array(
    0 => array(
        'gozhi' => 2,
        'uzorong' => 1,
        'ngangla' => 4,
        'langthel' => 5
    ),
    1 => array(
        'gozhi' => 5,
        'uzorong' => 0,
        'ngangla' => 3,
        'langthel' => 2
    ),
    2 => array(
        'gozhi' => 3,
        'uzorong' => 0,
        'ngangla' => 1,
        'langthel' => 3
    ),
);

$sumResult = call_user_func_array('array_map', array_merge(['sum'], $rArray));

function sum()
{
    return array_sum(func_get_args());
}

0 votes

Ceci additionne les colonnes en fonction de leur position -- et non par nom de colonne/clé. Cette réponse supprime également les clés associatives de la sortie. Cette réponse ne convient que si les colonnes sont déjà alignées et que le résultat est un tableau indexé de tableaux indexés. 3v4l.org/v0Tk3 et voici le code équivalent avec l'opérateur splat. 3v4l.org/9hM3V

12voto

Graviton Points 28358
$newarr=array();
foreach($arrs as $value)
{
  foreach($value as $key=>$secondValue)
   {
       if(!isset($newarr[$key]))
        {
           $newarr[$key]=0;
        }
       $newarr[$key]+=$secondValue;
   }
}

3 votes

Notez que cela vous donnera des avis PHP (undefined index) chaque fois que vous accédez à $newarr[$key] sur le côté droit de votre affectation, alors que ces valeurs n'existent pas encore.

0 votes

Je pense avoir ajouté une vérification pour initialiser le $newarr[$key]

4 votes

S'il vous plaît, laissez des commentaires si vous votez pour quelqu'un... Il n'y a aucun moyen d'améliorer la solution si vous ne laissez pas de commentaires.

5voto

Todd Chaffee Points 1329

Une autre version, avec quelques avantages ci-dessous.

$sum = ArrayHelper::copyKeys($arr[0]);

foreach ($arr as $item) {
    ArrayHelper::addArrays($sum, $item);
}

class ArrayHelper {

    public function addArrays(Array &$to, Array $from) {
        foreach ($from as $key=>$value) {
            $to[$key] += $value;
        }
    }

    public function copyKeys(Array $from, $init=0) {
        return array_fill_keys(array_keys($from), $init);
    }

}

Je voulais combiner le meilleur des réponses de Gumbo, Graviton et Chris J avec les objectifs suivants afin de pouvoir les utiliser dans mon application :

a) Initialiser les clés du tableau 'sum' en dehors de la boucle (Gumbo). Cela devrait améliorer les performances sur les très grands tableaux (pas encore testé !). Élimine les avis.

b) La logique principale est facile à comprendre sans avoir à consulter les manuels. (Graviton, Chris J).

c) Résoudre le problème plus général de l'addition des valeurs de deux tableaux ayant les mêmes clés et le rendre moins dépendant de la structure des sous-réseaux.

Contrairement à la solution de Gumbo, vous pouvez réutiliser cette méthode dans les cas où les valeurs ne sont pas dans des sous-réseaux. Imaginez dans l'exemple ci-dessous que $arr1 y $arr2 ne sont pas codées en dur, mais sont renvoyées comme résultat de l'appel d'une fonction à l'intérieur d'une boucle.

$arr1 = array(
    'gozhi' => 2,
    'uzorong' => 1,
    'ngangla' => 4,
    'langthel' => 5
);

$arr2 = array(
   'gozhi' => 5,
   'uzorong' => 0,
   'ngangla' => 3,
   'langthel' => 2
);

$sum = ArrayHelper::copyKeys($arr1);

ArrayHelper::addArrays($sum, $arr1);
ArrayHelper::addArrays($sum, $arr2);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X