2016-04-20 4 views
0

Ich habe eine Sammlung von Daten.Rekursive Array Map mit Laravel Collection map() Helper

$array = [ 

    [ 
     'id' => 1, 
     'name' => 'some1', 
     'type' => 'type1', 
     'color' => 'color1', 
     'quantity' => 1 
    ], 

    [ 
     'id' => 2, 
     'name' => 'some1', 
     'type' => 'type1', 
     'color' => 'color1', 
     'quantity' => 1 
    ], 

    [ 
     'id' => 3, 
     'name' => 'some1', 
     'type' => 'type1', 
     'color' => 'color2', 
     'quantity' => 1 
    ], 

    [ 
     'id' => 4, 
     'name' => 'some2', 
     'type' => 'color1', 
     'color' => 'type1', 
     'quantity' => 1 
    ], 

    ...... 
]; 

, die verschiedenen Namen, Typ und Farbe.

Ich möchte die Daten nach Name, Typ und Farbe gruppieren und das Ergebnis ist Array-Daten mit Zusammenfassung der gleichen Gruppendaten.

Zuerst verwende ich diese Art und Weise:

function groupedData($array) 
{ 

    $collection = []; 

    collect($array)->groupBy('name')->map(

     function ($item) use (&$collection) { 

      return $item->groupBy('type')->map(

       function ($item) use (&$collection) { 

        return $item->groupBy('color')->map(

         function ($item) use (&$collection) { 

          $quantity = $item->sum('quantity'); 
          $collection[] = collect($item[0])->merge(compact('quantity')); 
         } 
        ); 
       } 
      ); 
     } 
    ); 

    return $collection; 
} 

ich die Ausgabe erwarten so sein sollte:

$grouped = [ 

    [ 
     'id' => 1, 
     'name' => 'some1', 
     'type' => 'type1', 
     'color' => 'color1', 
     'quantity' => 2 
    ], 

    [ 
     'id' => 2, 
     'name' => 'some1', 
     'type' => 'type1', 
     'color' => 'color2', 
     'quantity' => 1 
    ], 

    [ 
     'id' => 3, 
     'name' => 'some2', 
     'type' => 'type1', 
     'color' => 'color1', 
     'quantity' => 2 
    ], 

    [ 
     'id' => 4, 
     'name' => 'some2', 
     'type' => 'type2', 
     'color' => 'color1', 
     'quantity' => 2 
    ], 
]; 

wo Menge der Anzahl der Gruppenelemente darstellen.

Aber ich das Problem ist, wenn die erforderliche geändert wird. Nur für den Fall: wenn Benutzer andere Kategorie für die Gruppierung hinzufügen möchten, Beispiel: Benutzer möchte nach Name, Typ, Farbe und Größe vielleicht gruppieren.

Frage: Wie man eine Funktion macht, die es einfacher und flexibler machen kann, so muss der Code nicht ändern, wenn die Anforderung ändert?

Danke für die Antwort.

+2

Ihr Code hat zwei 'return' Anweisungen, und es ist schwer zu folgen. Können Sie einige Beispielausgabedaten anzeigen? –

+0

Danke @JosephSilber Sorry, ich habe die Frage aktualisiert. :) –

Antwort

0

Was Sie suchen, sortieren, nicht gruppieren.

Hier ist eine einfache Möglichkeit, es zu tun:

function sort($array, $keys) { 
    return collect($array)->sortBy(function ($item) use ($keys) { 
     return array_reduce($keys, function ($carry, $key) use ($item) { 
      return $carry + $item[$key]; 
     }, ''); 
    })->all(); 
} 

Hier eine kurze Erklärung:

  1. Wir verwenden die sortBy Methode der Sammlung, die wir lassen ist eine Callback-Funktion zu verwenden, die zurückkehren würde eine Zeichenfolge, um die Sortierreihenfolge zu bestimmen.
  2. Wir verwenden array_reduce auf die Schlüssel, um eine einzelne Zeichenfolge aller Werte in den Schlüsseln zu erstellen, nach denen sortiert werden soll.
  3. Das Sammlungsobjekt von Laravel verwendet die resultierende Zeichenfolge, um die Sammlung zu ordnen.
  4. Schließlich rufen wir die all-Methode auf, um das zugrunde liegende Array aus der Auflistung abzurufen. Wenn Sie eine Sammlung tatsächlich zurückgeben möchten, können Sie den letzten Aufruf all entfernen.