paul1: PHP array bearbeiten

Hallo, ich habe ein Multiarray mit Datum, Uhrzeit und Messwert. Nun möchte ich aber für jeden Tag nur einen Wert haben. Bei Tagen mit meheren Messwerten sollen diese gemittelt werden.

array:
  '01.01.2022', '08:00', 100
  '01.01.2022', '12:00', 101
  '01.01.2022', '16:00', 102
  '02.01.2022', '12:00', 101
  '03.01.2022', '08:00', 102
  '03.01.2022', '16:00', 104
Ergebnis soll sein:
  '01.01.2022', 101
  '02.01.2022', 101
  '03.01.2022', 103

Gibt es dafür vielleicht eine passende PHP Funktion oder eine Kombination aus mehreren? Wenn nicht, wie könnte man das Problem elegant lösen?

Danke und Gruß, Paul

  1. Hallo paul1,

    machst Du Info-Hausaufgaben und ihr macht gerade Gruppenwechsel?

    Da programmierst Du eine Schleife, fragst ab, ob sich das Datum ändert. Solange es gleich bleibt, addierst Du auf und zählst, wieviele es sind. Sobald es sich ändert (und nach Schleifenende) schreibst Du das bearbeitete Datum zusammen mit dem Mittelwert weg. In ein neues Array oder ins HTML, wie es grad gebraucht wird.

    Ich würde Dich ansonsten noch auf den Gruppenwechsel Artikel im Selfwiki verweisen wollen. Der ist recht umfangreich und handelt das Thema ab.

    Rolf

    --
    sumpsi - posui - obstruxi
  2. Hallo

    Hallo, ich habe ein Multiarray mit Datum, Uhrzeit und Messwert. Nun möchte ich aber für jeden Tag nur einen Wert haben. Bei Tagen mit meheren Messwerten sollen diese gemittelt werden.

    array:
      '01.01.2022', '08:00', 100
      '01.01.2022', '12:00', 101
      '01.01.2022', '16:00', 102
      '02.01.2022', '12:00', 101
      '03.01.2022', '08:00', 102
      '03.01.2022', '16:00', 104
    

    Ich vermute richtig, wenn ich davon ausgehe, dass die eigentliche Struktur folgende ist?

    array:
      ['01.01.2022', '08:00', 100],
      ['01.01.2022', '12:00', 101],
      ['01.01.2022', '16:00', 102],
      ['02.01.2022', '12:00', 101],
      ['03.01.2022', '08:00', 102],
      ['03.01.2022', '16:00', 104]
    
    Ergebnis soll sein:
      '01.01.2022', 101
      '02.01.2022', 101
      '03.01.2022', 103
    

    Gibt es dafür vielleicht eine passende PHP Funktion oder eine Kombination aus mehreren? Wenn nicht, wie könnte man das Problem elegant lösen?

    Du brauchst die Information zu allen Werten und deren Anzahl, aufgesplittet nach Tagen. Dazu kann dein Array in einer Schleife durchlaufen und die Informationen in ein neues Array umgepackt werden. Das Ergebnis könnte dann folgendermaßen aussehen.

    array:
      ['01.01.2022'=>[101, 102, 103]],
      ['02.01.2022'=>[101]],
      ['03.01.2022'=>[101, 103]]
    

    Der Schlüssel des äußeren Arrays ist das Datum (die Uhrzeiten brauchst du an der Stelle nicht), der Wert ist jeweils ein Array aller Werte des Tages. Damit hättest du sowohl alle Werte als (mit count($array['01.01.2022'])) auch die Anzahl der Werte. Der Rest ist Addition der Werte und die anschließende Division durch die Anzahl der Werte.

    Ich hoffe nur, ich habe mich gerade nicht in der Syntax vertan. 😁

    Tschö, Auge

    --
    200 ist das neue 35.
    1. Hallo Auge,

      Dazu kann dein Array in einer Schleife durchlaufen und die Informationen in ein neues Array umgepackt werden.

      Wenn PHP eine fertige Funktion dafür hätte, wäre das ggf. sinnvoll. Dazu kenne ich aber nichts. Und wenn man eh die Schleife programmieren muss, würde ich auch direkt die Mittelwerte berechnen.

      FALLS man natürlich vorhat, sich einen Baukasten für funktionale Programmierung anzulegen, wäre es ein netter Startpunkt, sich eine solche Aggregate-Funktion zu schreiben 😉. Großes Array rein, aggregiertes Array raus. Oder einen ControlBreakIterator, mit dem man Gruppenwechsel steuern kann…

      Rolf

      --
      sumpsi - posui - obstruxi
      1. Hallo

        Dazu kann dein Array in einer Schleife durchlaufen und die Informationen in ein neues Array umgepackt werden.

        Wenn PHP eine fertige Funktion dafür hätte, wäre das ggf. sinnvoll. Dazu kenne ich aber nichts. Und wenn man eh die Schleife programmieren muss, würde ich auch direkt die Mittelwerte berechnen.

        Sauber ist das schon, aber das kann, gerade für Unerfahrene, unleserlich (weil zu komplex) sein. Du weißt ja, wer man ist, wenn man sich den Code ein halbes Jahr später anschaut. Deshalb habe ich diesen Zwischenschritt mit dem Array mit einer für diese Aufgabe grundsätzlich geeignete Datenstruktur eingefügt, weil ich das für die Erklärung verständlicher finde. Ich weiß ja nicht, wie komplex die Erklärung für Paul sein darf. Im besten Fall hilft die Schritt-für-Schritt-Erklärung ihm, etwas komplexeres zu schreiben, das über die Erklärung hinausgeht.

        FALLS man natürlich vorhat, sich einen Baukasten für funktionale Programmierung anzulegen, wäre es ein netter Startpunkt, sich eine solche Aggregate-Funktion zu schreiben 😉. Großes Array rein, aggregiertes Array raus. Oder einen ControlBreakIterator, mit dem man Gruppenwechsel steuern kann…

        Das natürlich prinzipiell sowieso.

        Tschö, Auge

        --
        200 ist das neue 35.
        1. Danke erstmal für Eure Antworten.

          Das hilft. Danke

          1. <?php
            
            header('Content-Type: text/plain');
            
            $arr = [
              [ '01.01.2022', '08:00', 100 ], # a.k.a. „Zeile“
              [ '01.01.2022', '12:00', 101 ],
              [ '01.01.2022', '16:00', 102 ],
              [ '02.01.2022', '12:00', 101 ],
              [ '03.01.2022', '08:00', 102 ],
              [ '03.01.2022', '16:00', 104 ]
            ];
            
            # Ok. Wir brauchen einen Hilfsarray:
            $helper = [];
            
            
            # Zeile für Zeile:
            foreach ( $arr as $row ) {
              # wenn es im Hilfsarray noch keine Zeile für das Datum gibt: 
              if ( empty(  $helper[ $row[0] ] )  ) {
                # Lege eine solche an und schreibe den Wert aus der 3. Spalte
                # in deren Spalte 'sum' und die 1 in die Spalte 'count' 
                $helper[ $row[0] ]['sum'] = $row[2];
                $helper[ $row[0] ]['count'] = 1;
              } else {
                # Addiere den Wert aus der 3. Spalte zur Spalte 'sum'
                # Erhöhe den Counter
                $helper[ $row[0] ]['sum'] += $row[2];
                $helper[ $row[0] ]['count'] ++;
              }
              echo '----------------------------------------------------' . PHP_EOL;
              echo 'Hilfsarray nach dem Einlesen einer (weiteren) Zeile:' . PHP_EOL;
              echo '----------------------------------------------------' . PHP_EOL;
              print_r( $helper);
            }
            
            # Fertíg? Ausgabe!
            
            echo '######################################' . PHP_EOL;
            
            foreach ( array_keys( $helper ) as $itemKey ) {
            	echo "$itemKey : ", $helper[$itemKey]['sum'] / $helper[$itemKey]['count'], PHP_EOL;
            }
            
            

            Ausgaben:

            ----------------------------------------------------
            Hilfsarray nach dem Einlesen einer (weiteren) Zeile:
            ----------------------------------------------------
            Array
            (
                [01.01.2022] => Array
                    (
                        [sum] => 100
                        [count] => 1
                    )
            
            )
            ----------------------------------------------------
            Hilfsarray nach dem Einlesen einer (weiteren) Zeile:
            ----------------------------------------------------
            Array
            (
                [01.01.2022] => Array
                    (
                        [sum] => 201
                        [count] => 2
                    )
            
            )
            ----------------------------------------------------
            Hilfsarray nach dem Einlesen einer (weiteren) Zeile:
            ----------------------------------------------------
            Array
            (
                [01.01.2022] => Array
                    (
                        [sum] => 303
                        [count] => 3
                    )
            
            )
            ----------------------------------------------------
            Hilfsarray nach dem Einlesen einer (weiteren) Zeile:
            ----------------------------------------------------
            Array
            (
                [01.01.2022] => Array
                    (
                        [sum] => 303
                        [count] => 3
                    )
            
                [02.01.2022] => Array
                    (
                        [sum] => 101
                        [count] => 1
                    )
            
            )
            ----------------------------------------------------
            Hilfsarray nach dem Einlesen einer (weiteren) Zeile:
            ----------------------------------------------------
            Array
            (
                [01.01.2022] => Array
                    (
                        [sum] => 303
                        [count] => 3
                    )
            
                [02.01.2022] => Array
                    (
                        [sum] => 101
                        [count] => 1
                    )
            
                [03.01.2022] => Array
                    (
                        [sum] => 102
                        [count] => 1
                    )
            
            )
            ----------------------------------------------------
            Hilfsarray nach dem Einlesen einer (weiteren) Zeile:
            ----------------------------------------------------
            Array
            (
                [01.01.2022] => Array
                    (
                        [sum] => 303
                        [count] => 3
                    )
            
                [02.01.2022] => Array
                    (
                        [sum] => 101
                        [count] => 1
                    )
            
                [03.01.2022] => Array
                    (
                        [sum] => 206
                        [count] => 2
                    )
            
            )
            ######################################
            01.01.2022 : 101
            02.01.2022 : 101
            03.01.2022 : 103
            
            

            Ach so: Manöverkritik

            • Die von Dir gezeigten Daten sehen „schwer subobtimal organisiert“ aus. Mormalerweise würde man einen Timestamp notieren.
            • Und falls die Daten in einer Datenbank liegen würde man eine Datenbankfunktion wie AVG("anzahl") und ein ``GROUP_BY "date" im SELECT verwenden...
            1. Hallo Raketenwilli,

              Angesichts meiner unwidersprochenen Vermutung, dass sich hier jemand die Hausaufgaben machen lassen möchte, hätte es mit dieser Lösung noch einen Tag Zeit gehabt... 😉

              Rolf

              --
              sumpsi - posui - obstruxi
              1. Hallo,

                noch einen Tag

                ja sicher. Aber dann hätte Willi das Risiko auf sich nehmen müssen, eventüll nicht raktenmüßig erster zu sein...

                Gruß
                Kalk

              2. Moin,

                Angesichts meiner unwidersprochenen Vermutung, dass sich hier jemand die Hausaufgaben machen lassen möchte, hätte es mit dieser Lösung noch einen Tag Zeit gehabt... 😉

                auf jeden Fall. Aber jetzt kann Paul eine Lösung präsentieren, die der Lehrer vielleicht gar nicht versteht. Den Fall hatte ich auch mal ...

                Klassenarbeit. Informatik-Grundkurs Klassenstufe 13, Schuljahr 1987/88. Unser Informatik-Lehrer war eigentlich ein Physiklehrer, der sich aber so nebenher mal ein bisschen mit Computerthemen befasst hatte. Ich weiß die genaue Aufgabenstellung nicht mehr, aber wir sollten einen Algorithmus "auf dem Trockenen" in BASIC hinschreiben.

                Als wir die Arbeiten korrigiert zurückbekamen, bat er mich: "Wollen Sie mir bitte Ihre Lösung erklären? Ich hab's ausprobiert, es funktioniert wirklich. Aber ich verstehe nicht, warum."

                Einen schönen Tag noch
                 Martin

                --
                "Hab ich vergessen" ist oft nur ein Euphemismus für "Hab ich noch nie verstanden".
                1. Aber jetzt kann Paul eine Lösung präsentieren, die der Lehrer vielleicht gar nicht versteht.

                  Also für den Fall habe ich z.B. die Zeile mit dem Content-Type eingebaut. Da kann der Lehrer das auch auf dem Strato- oder Schul-Server testen und sich die Ausgaben im Browser ansehen - ohne wissen zu müssen wie man an den vermeintlichen HTML-Quelltext rankommt.

                  Ich hätte vermutlich Punktabzug bekommen, weil ich mich fürchterhafterlich über die Eingangsdaten aufgeregt hätte…

                  Und Mutti („Woll! Die war Lehrerin!“) hätte die mangelhafte Grammatik in den Kommentaren moniert...

                2. Hallo Martin,

                  Es funktioniert wirklich. Aber ich verstehe nicht, warum.

                  Hach ja, the story of my life...

                  Rolf

                  --
                  sumpsi - posui - obstruxi
  3. Ich verstehe das Ergebnis nicht ...

    01.01.2022, 101 -> Ist anscheinend das mittlere Ergebnis?
    02.01.2022, 101 -> Ist das einzige Ergebnisse!
    03.01.2022, 103 -> Ist im Ausgangsarray gar nicht vorhanden.

    Also ich weiß nicht wie man dir helfen soll. Die Datengrundlage oder das was am Ende rauskommen soll, sind mir ein Rätsel. Oder sollen die Zahlen in Fibonacci style hochzählen?

    Gruß
    Puzzlekönig
    T-Rex

    1. Ich verstehe das Ergebnis nicht ...

      01.01.2022, 101 -> Ist anscheinend das mittlere Ergebnis?
      02.01.2022, 101 -> Ist das einzige Ergebnisse!
      03.01.2022, 103 -> Ist im Ausgangsarray gar nicht vorhanden.

      Also ich weiß nicht wie man dir helfen soll. Die Datengrundlage oder das was am Ende rauskommen soll, sind mir ein Rätsel. Oder sollen die Zahlen in Fibonacci style hochzählen?

      Hm. Lesen?

      Bei Tagen mit meheren Messwerten sollen diese gemittelt werden.

      Ich wusste nur nicht, ob mit „gemittelt“ nun der „arithmetische Mittelwert“ oder der „Median“ gemeint war. Ich habe mich für den „arithmetischen Mittelwert“ entschieden, weil „Median“ (wohl) explizit erwähnt worden wäre.

      Frappierender Weise hat der TO die Werte so gewählt, das in beiden Fällen („arithmetischer Mittelwert“ a.k.a. „Durchschnitt“, „Median“) die Ergebnisse identisch sind...


      Programmierer drücken sich genau aus. Juristen lügen.