1unitedpower: Ausgabe in Kategorien zusammenfassen

Beitrag lesen

Das Ergebnisarray sollte zweckmäßigerweise nach der Spalte, nach der Du die Gruppen bilden willst, sortiert sein. Dann funktiniert der Gruppenwechsel so, wie Dedlfix ihn schon kurz beschrieben hat.

Das ist kein Muss und kann teilweise sogar unerwünscht sein. Wenn man einen eher funktionalen Ansatz wählt, dann kann diese Randbedingung, die sich bei prozeduraler Programmierung ergibt, vermieden werden. Ich würde auch dazu tendieren, den Gruppenwechsel von der unmittelbaren Ausgabe zu entkoppeln und stattdessen in einem Zwischenschritt für jede Gruppe eine eigene Kollektion anzulegen, sodass man ein Array von Arrays erhält. Zum Beispiel:

$groups = array_reduce($flatArray, function ($accumulator, $entry){
   $group = $entry['p_pkategorie'];
   if (!is_array($accumulator[$group]) {
      $accumulator[$group]] = array();
   }
   $accumulator[$group][] = $entry;
   return $accumulator
}, array());

In diesem Snippet wird das flache Eingabearray $flatArray Zeile für Zeile durchlaufen, für jeden Eintrag im Array wird dann festgestellt, ob es bereits eine Kollektion für die zugehörige Gruppe gibt. Falls nicht, dann wird ein neue Kollektion angelegt. Am Ende einer Iteration wird der Eintrag schließlich der Kollektion hinzugefügt.

Dieser Gruppenwechsel ist leider nicht wirklich wiederverwendbar, weil $entry['p_pkategorie'] für diesen speziellen Gruppenwechsel zugeschnitten ist, das Verhalten kann man weiter abstrahieren und sich so eine wiederverwendbare Funktion für den Gruppenwechsel basteln:

function groupBy ($column, array $flatArray) {
   return array_reduce($flatArray, function ($accumulator, $entry) use ($column) {
      $group = $entry[$column];
      if (!is_array($accumulator[$group]) {
         $accumulator[$group] = array();
      }
      $accumulator[$group][] = $entry;
      return $accumulator
   }, array());
}

Diese Funktion ist wiederverwendbar und in der Praxis für viele Fälle ausreichend. Manchmal hat man aber auch den Fall, dass man den Gruppenwechsel nicht einfach an einer Spalte im Array ausmachen kann, zum Beispiel wenn die Einträge im Eingabearray Objekte sind, oder wenn die Gruppenzugehörigkeit aus mehreren Spalten/Eigenschaften eines Eintrags abgeleitet wird. Wir können unsere Funktion weiter abstrahieren, indem wir als ersten Parameter keinen Spaltennamen mehr entgegen nehmen, sondern einfach eine Funktion, die die Gruppenzugehörigkeit auf irgendein beliebige Art ermittelt.

function groupBy (callable $groupId, array $flatArray) {
   return array_reduce( $flatArray, function ($accumulator, $entry) use ($groupId) {
      $group = groupId($entry);
      if (!is_array($accumulator[$group]) {
         $accumulator[$group] = array();
      }
      $accumulator[$group][] = $entry;
      return $accumulator
   }, array());
}