Arrays auswerten und zu einem neuen Array zusammenfassen

Fragen zu allen Themen rund ums Programmieren außerhalb von phpBB können hier gestellt werden - auch zu anderen Programmiersprachen oder Software wie Webservern und Editoren.
Antworten
phpfrage
Mitglied
Beiträge: 4
Registriert: 20.05.2015 15:26

Arrays auswerten und zu einem neuen Array zusammenfassen

Beitrag 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?
Benutzeravatar
gn#36
Ehrenadmin
Beiträge: 9313
Registriert: 01.10.2006 16:20
Wohnort: Ganz in der Nähe...
Kontaktdaten:

Re: Arrays auswerten und zu einem neuen Array zusammenfassen

Beitrag 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'];
    }
}
Begegnungen mit dem Chaos sind fast unvermeidlich, Aber nicht katastrophal, solange man den Durchblick behält.
Übertreiben sollte man's im Forum aber nicht mit dem Chaos, denn da sollen ja andere durchblicken und nicht nur man selbst.
phpfrage
Mitglied
Beiträge: 4
Registriert: 20.05.2015 15:26

Re: Arrays auswerten und zu einem neuen Array zusammenfassen

Beitrag 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...?
Benutzeravatar
gn#36
Ehrenadmin
Beiträge: 9313
Registriert: 01.10.2006 16:20
Wohnort: Ganz in der Nähe...
Kontaktdaten:

Re: Arrays auswerten und zu einem neuen Array zusammenfassen

Beitrag 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.
Begegnungen mit dem Chaos sind fast unvermeidlich, Aber nicht katastrophal, solange man den Durchblick behält.
Übertreiben sollte man's im Forum aber nicht mit dem Chaos, denn da sollen ja andere durchblicken und nicht nur man selbst.
DerPate
Mitglied
Beiträge: 157
Registriert: 12.06.2003 22:49

Re: Arrays auswerten und zu einem neuen Array zusammenfassen

Beitrag 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>';
} 
Antworten

Zurück zu „Coding & Technik“