Wie summiere ich alle Spaltenwerte in einem mehrdimensionalen Array?

116

Wie kann ich alle Spaltenwerte per Assoziativschlüssel hinzufügen? Beachten Sie, dass Schlüsselsätze dynamisch sind.

Eingabearray:

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

Erwünschtes Ergebnis:

Array
(
    [gozhi] => 10
    [uzorong] => 1
    [ngangla] => 8
    [langthel] => 10
)
marknt15
quelle
In einer häufigen Situation haben zwei mehrdimensionale Arrays nicht genau dieselben Schlüssel. Merge / Sum Multi Dimentional Array PHP
Kris Roofe

Antworten:

92
$sumArray = array();

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

print_r($sumArray);
Chris J.
quelle
49
Dadurch werden Benachrichtigungen für die erste Iteration ausgegeben, da die Schlüssel noch nicht vorhanden sind.
Gumbo
Wenn es n Arrays gibt?
Muhammad Usman
2
@RanaMuhammadUsman: Wenn nArrays vorhanden sind , verwenden Sie diese Lösung .
Amal Murali
2
array_reduce klingt für mich am schönsten stackoverflow.com/questions/14195916/…
Bill'o
13
Um die Hinweise zu vermeiden, können Sie die Zeile ersetzen, in der die Werte dem $ sumArray zugewiesen werden: array_key_exists ($ id, $ sumArray)? $ sumArray [$ id] + = $ value: $ sumArray [$ id] = $ value;
Dave O'Brien
185

Sie können verwenden array_walk_recursive(), um eine allgemeine Lösung für Ihr Problem zu erhalten ( die, wenn jedes innere Array möglicherweise eindeutige Schlüssel haben kann ).

$final = array();

array_walk_recursive($input, function($item, $key) use (&$final){
    $final[$key] = isset($final[$key]) ?  $item + $final[$key] : $item;
});

Beispiel mit array_walk_recursive()für den allgemeinen Fall

Da auch 5.5 PHP können Sie die verwenden array_column()Funktion das gewünschte Ergebnis zu erreichen , für die genauen Schlüssel , [gozhi]zum Beispiel:

array_sum(array_column($input, 'gozhi')); 

Beispiel mit array_column()für den angegebenen Schlüssel

Wenn Sie die Gesamtsumme aller inneren Arrays mit denselben Schlüsseln erhalten möchten ( das gewünschte Ergebnis, das Sie veröffentlicht haben ), können Sie Folgendes tun ( wobei zu berücksichtigen ist, dass das erste innere Array dieselbe Struktur wie die anderen haben muss ):

$final = array_shift($input);

foreach ($final as $key => &$value){
   $value += array_sum(array_column($input, $key));
}    

unset($value);

Beispiel mit array_column()für den Fall, dass alle inneren Arrays die gleichen Schlüssel haben

Wenn Sie eine allgemeine Lösung mit verwenden möchten array_column(), können Sie zunächst alle eindeutigen Schlüssel abrufen und dann die Summe für jeden Schlüssel abrufen:

$final = array();

foreach($input as $value)
    $final = array_merge($final, $value);

foreach($final as $key => &$value)
    $value = array_sum(array_column($input, $key));

unset($value);

Beispiel mit array_column()für den allgemeinen Fall

Kali
quelle
30

Verwenden Sie dieses Snippet:

$key = 'gozhi';
$sum = array_sum(array_column($array,$key));
Tan Ory Jaka Perdana
quelle
Ich habe die Frage bearbeitet, um zu verdeutlichen, dass diese Lösung im Hinblick auf die Bereitstellung der gewünschten Ausgabe des OP etwas verkocht ist. Das heißt, wenn Sie Ihre Antwort erweitern würden, würde es sehr wahrscheinlich zu einem Duplikat früher geposteter Antworten werden.
Mickmackusa
28

Hier ist eine ähnliche Lösung wie die beiden anderen:

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

Dies muss jedoch nicht überprüfen, ob die Array-Schlüssel bereits vorhanden sind, und es werden auch keine Benachrichtigungen ausgegeben.

Gumbo
quelle
+1 sehr clevere Lösung für diese spezielle Array-Struktur. Schade, dass es im allgemeineren Fall von Arrays, die alle wie das Endergebnis strukturiert sind, nicht funktioniert.
Todd Chaffee
22

Dies kann auch erfolgen mit 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());
}
npcoda
quelle
1
Perfekt für n Array-Zahlen
Dushyant Joshi
1
Wie würden Sie dies für N Array-Nummern ändern?
Pathros
12
$newarr=array();
foreach($arrs as $value)
{
  foreach($value as $key=>$secondValue)
   {
       if(!isset($newarr[$key]))
        {
           $newarr[$key]=0;
        }
       $newarr[$key]+=$secondValue;
   }
}
Graviton
quelle
3
Beachten Sie, dass Sie dadurch jedes Mal, wenn Sie auf $ newarr [$ key] auf der rechten Seite Ihrer Zuweisung zugreifen, PHP-Benachrichtigungen (undefinierter Index) erhalten, wenn solche Werte noch nicht vorhanden sind.
Anti Veeranna
Ich denke, ich füge einen Scheck hinzu, um den $ newarr [$ key]
Graviton
4
BITTE hinterlassen Sie Kommentare, wenn Sie jemanden ablehnen ... Es gibt keine Möglichkeit, die Lösung zu verbessern, wenn Sie keine Kommentare hinterlassen.
Todd Chaffee
@Graviton Ich habe nicht abgelehnt, aber ich werde sagen, dass jede StackOverflow-Antwort eine Erklärung enthalten sollte, wie die Lösung funktioniert und / oder warum sie ratsam ist. Denken Sie daran, dass jede Seite dieser Website / dieses Netzwerks eine Bildungsressource für Tausende und Abertausende von Entwicklern mit einem breiten Spektrum an Fähigkeiten / Kenntnissen ist. (Wenn ich jedes Mal, wenn ich eine Nur-Code-Antwort fand, abstimmte, gingen mir die Wiederholungspunkte aus.)
mickmackusa
5

Eine andere Version mit einigen Vorteilen unten.

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

}

Ich wollte das Beste aus der Antwort von Gumbo, Graviton und Chris J mit den folgenden Zielen kombinieren, damit ich dies in meiner App verwenden kann:

a) Initialisieren Sie die 'sum'-Array-Schlüssel außerhalb der Schleife (Gumbo). Sollte bei der Leistung auf sehr großen Arrays helfen (noch nicht getestet!). Beseitigt Benachrichtigungen.

b) Die Hauptlogik ist leicht zu verstehen, ohne die Handbücher zu lesen. (Graviton, Chris J).

c) Lösen Sie das allgemeinere Problem des Hinzufügens der Werte von zwei beliebigen Arrays mit denselben Schlüsseln und machen Sie es weniger abhängig von der Subarray-Struktur.

Im Gegensatz zur Lösung von Gumbo können Sie dies in Fällen wiederverwenden, in denen sich die Werte nicht in Unterarrays befinden. Stellen Sie sich in dem folgenden Beispiel , daß $arr1und $arr2sind nicht fest codiert, sondern werden als das Ergebnis der Aufruf einer Funktion in einer Schleife zurückgeführt .

$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);
Todd Chaffee
quelle
4

Dies kann auch erfolgen mit array_walk:

function array_sum_values(array $input, $key) {
   $sum = 0;
   array_walk($input, function($item, $index, $params) {
         if (!empty($item[$params[1]]))
            $params[0] += $item[$params[1]];
      }, array(&$sum, $key)
   );
   return $sum;
}

var_dump(array_sum_values($arr, 'gozhi'));

Nicht so lesbar wie frühere Lösungen, aber es funktioniert :)

Filip Górczyński
quelle
3

Hier ist eine Version, in der die Array-Schlüssel möglicherweise nicht für beide Arrays gleich sind, Sie jedoch möchten, dass sie alle im endgültigen Array vorhanden sind.

function array_add_by_key( $array1, $array2 ) {
    foreach ( $array2 as $k => $a ) {
        if ( array_key_exists( $k, $array1 ) ) {
            $array1[$k] += $a;
        } else {
            $array1[$k] = $a;
        }
    }
    return $array1;
}
Bollis
quelle
3

Wir müssen zuerst prüfen, ob ein Array-Schlüssel vorhanden ist.

CODE:

$sum = array();
foreach ($array as $key => $sub_array) {
    foreach ($sub_array as $sub_key => $value) {

        //If array key doesn't exists then create and initize first before we add a value.
        //Without this we will have an Undefined index error.
        if( ! array_key_exists($sub_key, $sum)) $sum[$sub_key] = 0;

        //Add Value
        $sum[$sub_key]+=$value;
    }
}
print_r($sum);

AUSGABE mit Array-Schlüsselüberprüfung:

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

AUSGABE ohne Überprüfung des Array-Schlüssels:

Notice: Undefined index: gozhi in F:\web\index.php on line 37

Notice: Undefined index: uzorong in F:\web\index.php on line 37

Notice: Undefined index: ngangla in F:\web\index.php on line 37

Notice: Undefined index: langthel in F:\web\index.php on line 37

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

Dies ist eine schlechte Vorgehensweise, obwohl die Ausgabe gedruckt wird. Überprüfen Sie immer zuerst, ob ein Schlüssel vorhanden ist.

Blauer Baum
quelle
1

Für diejenigen, die hier gelandet sind und nach einer Lösung suchen, die N Arrays zusammenführt UND auch die Werte identischer Schlüssel in den N Arrays summiert, habe ich diese Funktion geschrieben, die auch rekursiv funktioniert. (Siehe: https://gist.github.com/Nickology/f700e319cbafab5eaedc )

Beispiel:

$a = array( "A" => "bob", "sum" => 10, "C" => array("x","y","z" => 50) );
$b = array( "A" => "max", "sum" => 12, "C" => array("x","y","z" => 45) );
$c = array( "A" => "tom", "sum" =>  8, "C" => array("x","y","z" => 50, "w" => 1) );

print_r(array_merge_recursive_numeric($a,$b,$c));

Wird darin enden, dass:

Array
(
    [A] => tom
    [sum] => 30
    [C] => Array
        (
            [0] => x
            [1] => y
            [z] => 145
            [w] => 1
        )

)

Hier ist der Code:

<?php 
/**
 * array_merge_recursive_numeric function.  Merges N arrays into one array AND sums the values of identical keys.
 * WARNING: If keys have values of different types, the latter values replace the previous ones.
 * 
 * Source: https://gist.github.com/Nickology/f700e319cbafab5eaedc
 * @params N arrays (all parameters must be arrays)
 * @author Nick Jouannem <[email protected]>
 * @access public
 * @return void
 */
function array_merge_recursive_numeric() {

    // Gather all arrays
    $arrays = func_get_args();

    // If there's only one array, it's already merged
    if (count($arrays)==1) {
        return $arrays[0];
    }

    // Remove any items in $arrays that are NOT arrays
    foreach($arrays as $key => $array) {
        if (!is_array($array)) {
            unset($arrays[$key]);
        }
    }

    // We start by setting the first array as our final array.
    // We will merge all other arrays with this one.
    $final = array_shift($arrays);

    foreach($arrays as $b) {

        foreach($final as $key => $value) {

            // If $key does not exist in $b, then it is unique and can be safely merged
            if (!isset($b[$key])) {

                $final[$key] = $value;

            } else {

                // If $key is present in $b, then we need to merge and sum numeric values in both
                if ( is_numeric($value) && is_numeric($b[$key]) ) {
                    // If both values for these keys are numeric, we sum them
                    $final[$key] = $value + $b[$key];
                } else if (is_array($value) && is_array($b[$key])) {
                    // If both values are arrays, we recursively call ourself
                    $final[$key] = array_merge_recursive_numeric($value, $b[$key]);
                } else {
                    // If both keys exist but differ in type, then we cannot merge them.
                    // In this scenario, we will $b's value for $key is used
                    $final[$key] = $b[$key];
                }

            }

        }

        // Finally, we need to merge any keys that exist only in $b
        foreach($b as $key => $value) {
            if (!isset($final[$key])) {
                $final[$key] = $value;
            }
        }

    }

    return $final;

}

?>
Nick
quelle
1

Gehen Sie jedes Element des Arrays durch und summieren Sie die Werte zu den vorherigen Werten, falls vorhanden, wenn Sie nicht nur den Wert zuweisen.

<?php
$array = 
[
    [
        'a'=>1,
        'b'=>1,
        'c'=>1,
    ],
    [
        'a'=>2,
        'b'=>2,
    ],
    [
        'a'=>3,
        'd'=>3,
    ]
];

$result = array_reduce($array, function($carry, $item) {
    foreach($item as $k => $v)
        $carry[$k] = $v + ($carry[$k] ?? 0);

    return $carry;
}, []);

print_r($result);

Ausgabe:

Array
(
    [a] => 6
    [b] => 3
    [c] => 1
    [d] => 3
)

Oder durchlaufen Sie einfach jedes Unterarray und gruppieren Sie die Werte für jede Spalte. Fassen Sie sie schließlich zusammen:

foreach($array as $subarray)
    foreach($subarray as $key => $value)
        $grouped[$key][] = $value;

$sums = array_map('array_sum', $grouped);
Progrock
quelle
0

Hier haben Sie, wie ich diese Art von Operationen normalerweise mache.

// We declare an empty array in wich we will store the results
$sumArray = array();

// We loop through all the key-value pairs in $myArray
foreach ($myArray as $k=>$subArray) {

   // Each value is an array, we loop through it
   foreach ($subArray as $id=>$value) {

       // If $sumArray has not $id as key we initialize it to zero  
       if(!isset($sumArray[$id])){
           $sumArray[$id] = 0;
       }

       // If the array already has a key named $id, we increment its value
       $sumArray[$id]+=$value;
    }
 }

 print_r($sumArray);
Luis González
quelle
Könnten Sie bitte eine Erklärung zu diesem Code geben und warum er die Frage beantwortet? Es ist hilfreicher, als nur einen Codeblock ohne Erklärung zu sichern.
Trincot
natürlich!! Entschuldigung, ich bin Spanier und erkläre mir, dass der Code das Schwierigste ist, wenn ich eine Frage beantworte! Vielen Dank für Ihren Rat @trincot
Luis González
0

Sie können dies versuchen:

$c = array_map(function () {
      return array_sum(func_get_args());
     },$a, $b);

und schlussendlich:

print_r($c);
1990rk4
quelle
1
Wofür verwenden Sie genau $aund $bwann rufen Sie an array_map()? Bitte verbessern Sie diese Nur-Code-Antwort.
Mickmackusa
0

Das funktioniert hervorragend bei meinem Laravel-Projekt

print_r($Array); // your original array

$_SUM = [];

// count($Array[0]) => if the number of keys are equall in all arrays then do a count of index 0 etc.
for ($i=0; $i < count($Array[0]); $i++) {
    $_SUM[] = $Array[0][$i] + $Array[1][$i]; // do a for loop on the count 
}

print_r($_SUM); // get a sumed up array
Maurice Wagura
quelle
Dies funktioniert möglicherweise für Ihr Laravel-Projekt, ist jedoch keine gute / praktikable Lösung für DIESE Frage.
Mickmackusa
-1
$sumArray = array();
foreach ($myArray as $k => $subArray) {
    foreach ($subArray as $id => $value) {
        if (!isset($sumArray[$id])) {
            $sumArray[$id] = 0;
        }
        $sumArray[$id]+=$value;
    }
}
Channeth Khon
quelle
Dies ist ein Duplikat einer Antwort von VIELEN Jahren zuvor. stackoverflow.com/a/1496697/2943403 Bitte lesen Sie alle vorhandenen Antworten, bevor Sie Ihre eigenen veröffentlichen, damit auf derselben Seite keine Redundanzen auftreten.
Mickmackusa
-1
$sumArray = array();

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

print_r($sumArray);

`
Soliman Mahmoud Soliman
quelle
Bitte überprüfen Sie, wie ich eine gute Antwort schreibe . Von Nur-Code-Antworten wird abgeraten, da sie nicht erklären, wie sie das Problem in der Frage lösen. Sie sollten Ihre Antwort aktualisieren, um zu erklären, was dies bewirkt und wie es die vielen positiven Antworten verbessert, die diese 8-jährige Frage bereits hat.
FluffyKitten
Grundsätzlich ein Duplikat einer früheren Antwort: stackoverflow.com/a/20532196/2943403
mickmackusa
-2

Sie können beispielsweise alle Felder aus einem Ergebnis wie dem folgenden abrufen.

Ich wähle den 'Saldo' aus einem Array aus und speichere ihn in einer Variablen

$kii =   $user->pluck('balance');

dann kannst du in der nächsten Zeile so summieren:

$sum =  $kii->sum(); 

Ich hoffe es hilft.

Emmanuel Iyen-Mediatrees
quelle