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
)

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

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


30

Verwenden Sie dieses Snippet:

$key = 'gozhi';
$sum = array_sum(array_column($array,$key));

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.


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

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

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

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


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

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.


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 <nick@nickology.com>
 * @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;

}

?>

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

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

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

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

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

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

`

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.