Seite 1 von 1

Arrays auswerten und zu einem neuen Array zusammenfassen

Verfasst: 20.05.2015 15:37
von phpfrage
Hallo, ich habe mehrere Arrays mit doppelten Nutzereinträgen. Ich möchte die Arrays nach den gleichen Nachnamen
durchsuchen und ein neues Array zusammenstelllen wo die Stunden für den jeweils Nutzer zusammen addiert werden. Meine
Code wäre folgender:

Code: Alles auswählen

<?php
//Debugging einschalten
error_reporting(-1);
ini_set('display_errors', true);

$rohdaten = array();
$auswertung = array();
 
$rohdaten[0]['vorname']   = 'Max';
$rohdaten[0]['nachname'] = 'Lustig';
$rohdaten[0]['stunden']    = 2.30;
 
$rohdaten[1]['vorname']   = 'Max';
$rohdaten[1]['nachname'] = 'Lustig';
$rohdaten[1]['stunden']    = 1.50;
 
$rohdaten[2]['vorname']   = 'Hans';
$rohdaten[2]['nachname'] = 'Dampf';
$rohdaten[2]['stunden']    = 5.10;
 
$rohdaten[3]['vorname']   = 'Hans';
$rohdaten[3]['nachname'] = 'Dampf';
$rohdaten[3]['stunden']    = 1.25;
 

for($a = 0; $a < count($rohdaten); $a++){
  //Prüfen ob Nachname bereits vorhanden
  $nachname = $rohdaten[$a]['nachname'];
  var_dump($a, $nachname, count($rohdaten));

  If ($a == 0) {
    //erster Datensatz in Array $auswertung definieren
    $auswertung[1]['vorname'] = $rohdaten[$a]['vorname'];
    $auswertung[1]['nachname'] = $rohdaten[$a]['nachname'];
    $auswertung[1]['stunden'] = $rohdaten[$a]['stunden'];
  }
  else{
    for($b=0; $b < count($auswertung); $b++){
       If ($auswertung[$b]['nachname'] = $nachname){
          //Nachname wurde in $auswertung gefunden
          $auswertung[$b]['stunden'] = $auswertung[$b]['stunden'] + $rohdaten[$a]['stunden'];            
       }
       else{
          //Nachname wurde nicht in $auswertung gefunden
          //$b = $zaehler + 1;
          $auswertung[$b+1]['vorname'] = $rohdaten[$a]['vorname'];
          $auswertung[$b+1]['nachname'] = $rohdaten[$a]['nachname'];
          $auswertung[$b+1]['stunden'] = $rohdaten[$a]['stunden'];
       }
     }
  }    
}

//Datenauswertung ausgeben   
for($i=0; $i < count($auswertung); $i++){
  echo $auswertung[$i]['vorname'];
  echo $auswertung[$i]['nachname'];
  echo $auswertung[$i]['stunden'];
  echo '<br>';
}

?>
Ausgabe:
Notice: Undefined index: stunden in line 42

Notice: Undefined index: vorname in line 57
Dampf7.85
MaxDampf10.15

Ich habe daraufhin den Debug-Modus aktiviert und mir in der ersten FOR-a-Schleife folgendes
ausgeben lassen: var_dump($a, $nachname, count($rohdaten));

Ausgabe:
int(0) string(6) "Lustig" int(4) int(1) string(6) "Lustig" int(4)
Notice: Undefined index: stunden in G:\Programme\Xampp\htdocs\01.Projekte.xampp\Auswer tungHW\_test.php on line 42
int(2) string(5) "Dampf" int(4) int(3) string(5) "Dampf" int(4)
Notice: Undefined index: vorname in G:\Programme\Xampp\htdocs\01.Projekte.xampp\Auswer tungHW\_test.php on line 57
Dampf7.85
MaxDampf10.15

Es sieht also so aus, als wenn er die FOR-a-Schleife nicht bis 4 durchläuft oder?
Ist meine Heransgehenweise generell richtig oder gibt es für mein Problem auch noch elegantere Lösungen?

Re: Arrays auswerten und zu einem neuen Array zusammenfassen

Verfasst: 20.05.2015 17:58
von gn#36
Da ist ein Tippfehler in deinem Code:
If ($auswertung[$b]['nachname'] = $nachname){ Das = sollte besser ein == sein ;) So führt das vermutlich dazu, dass du immer den ersten Eintrag überschreibst.

Außerdem ist systematisch was falsch: Du prüfst mit der if/else Konstruktion in der for($b ...) Schleife, ob der aktuelle Eintrag identisch ist mit dem gefundenen Nachnamen. Wenn nicht, wird aber sofort bei dem ersten Element schon das zweite Element überschrieben im else Teil. Du weißt aber erst sicher, dass du niemanden gefunden hast, wenn du die komplette Schleife durch bist und zu keinem Zeitpunkt was geändert hast.

Geschwindigkeitsmäßig lässt sich das dann anschließend auch noch optimieren: Sobald du einen Eintrag in deinem Array gefunden hast der passt weißt du, dass du nicht mehr weiter suchen musst. Du kannst dann addieren und anschließend mit break die aktuelle Schleife abbrechen.

Einfacher würde die ganze Sache auch gehen, indem du ein assoziatives Array baust. Dann musst du nur 1x dein Ursprungsarray durchlaufen und kannst die Werte einfach aufaddieren:

Code: Alles auswählen

$rohdaten = ...;
$auswertung = array();
foreach($rohdaten as $row)
{
    if(!isset($auswertung[$row['name']]))
    {
        $auswertung[$row['name']] = $row;
    }
    else
    {
        $auswertung[$row['name']]['stunden'] += $row['stunden'];
    }
}

Re: Arrays auswerten und zu einem neuen Array zusammenfassen

Verfasst: 21.05.2015 10:45
von phpfrage
Hallo gn#36,

ich danke dir für deinen Beitrag. Dein Bsp. mit Foreach ist viel übersichtlicher, als meine
FOR-Schleife. Allerdings verstehe ich nicht ganz den Syntax deiner IF-Else-Anweisung (Ja bin
Anfänger...).

Mein Verständnis:
If-Bedingung: Wenn Nachname existiert im Array $auswertung
Anweisung: summiere nur die Stunden für den jeweiligen Nachnamen
else: ansonsten lege Nachname, sowie momentanen Stundenwert im neuen Array an

Laut deinem Syntax sieht das für mich genau andersrum aus...?

Code: Alles auswählen

 if(!isset($auswertung[$row['nachname']]))
--> bedeutet doch: wenn Nachname im Array $auswertung existiert

Code: Alles auswählen

 $auswertung[$row['nachname']] = $row;

--> bedeutet doch: das das komlette Array an der Stelle $row[nachname] in $auswertung
übernommen werden soll (also mit Vorname, Nachname, Stunden)

Code: Alles auswählen

 $auswertung[$row['nachname']]['stunden'] += $row['stunden'];

--> bedeutet doch das die neuen Stunden zum Array dazu addiert werden, aber woher weiß er
er das er die Stunden zum Feld [stunden] addieren soll und nicht zum Feld [nachname]
--> da [stunden] der letzte Wert vor dem Plus-Zeichen ist oder anhand der Namensgebung
($row[stunden] kann nur mit [$row[stunden] addiert werden...?

Re: Arrays auswerten und zu einem neuen Array zusammenfassen

Verfasst: 21.05.2015 12:25
von gn#36
phpfrage hat geschrieben:Mein Verständnis:
If-Bedingung: Wenn Nachname existiert im Array $auswertung
[...]

Code: Alles auswählen

 if(!isset($auswertung[$row['nachname']])) 
--> bedeutet doch: wenn Nachname im Array $auswertung existiert
Nein, genau das Gegenteil. Wenn der Name nicht existiert. Da ist ein ! vor dem isset, der die Prüfung negiert. Letztlich ist das aber egal - man kann auch die Negierung weglassen und dann if und else Anweisungen vertauschen.

Code: Alles auswählen

 $auswertung[$row['nachname']] = $row; 

--> bedeutet doch: das das komlette Array an der Stelle $row[nachname] in $auswertung
übernommen werden soll (also mit Vorname, Nachname, Stunden)
Richtig.

Code: Alles auswählen

 $auswertung[$row['nachname']]['stunden'] += $row['stunden']; 

--> bedeutet doch das die neuen Stunden zum Array dazu addiert werden, aber woher weiß er
er das er die Stunden zum Feld [stunden] addieren soll und nicht zum Feld [nachname]
--> da [stunden] der letzte Wert vor dem Plus-Zeichen ist oder anhand der Namensgebung
($row[stunden] kann nur mit [$row[stunden] addiert werden...?
Auch richtig. Der Zugriff $auswertung[$row['nachname']]['stunden'] greift genau auf den stunden Eintrag zu. Wenn man es mal farblich aufschlüsselt:
$auswertung[$row['nachname']]['stunden']
Die Variable $row['nachname'] wird einfach als key in das array $auswertung eingesetzt und wählt die Person aus. Dann nimmt man dieses Array und greift darin auf das Element stunden zu.

Das += ist einfach eine Abkürzung. $a += $b ist gleichbedeutend mit $a = $a + $b. Das gilt für beliebige Variablen. Dementsprechend hast du recht, das += bezieht sich auf das letzte Element vor dem Symbol und addiert diesem etwas hinzu. Die Syntax ist hier identisch mit C.

Re: Arrays auswerten und zu einem neuen Array zusammenfassen

Verfasst: 21.05.2015 18:46
von DerPate
Tach, nochn anderer Ansatz, in dem die Stunden als Array gesammlt werden ...

Code: Alles auswählen

foreach ($rohdaten as $row) {
    $auswertung[$row['nachname']][] = $row['stunden'];
}

foreach ($auswertung as $name => $stundenArray) {
    $summe = array_sum($stundenArray);
    echo $name . ': ' . $summe . ' (' . $summe/count($stundenArray). ')<br>';
}