JavaScript/Objekte/Array/reduce

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Die Methode reduce ruft die angegebene Rückruffunktion (Callback) für alle Elemente in einem Array auf, mit dem Ziel, den Array-Inhalt auf einen einzigen Wert zu reduzieren. Einsatzzweck kann zum Beispiel eine Summen- oder Durchschnittsbildung sein.

Syntax
ergebnis = arr.reduce(callback[, anfangsWert])
  • callback: Funktion, die für jeden Wert im Array ausgeführt wird und 4 Argumente übergeben bekommt:
    • previousValue: Der vom letzten Aufruf dieser Funktion zurückgegebene Wert, oder ein Anfangswert. Details dazu weiter unten.
    • currentValue: Das aktuelle im Array verarbeitete Element
    • index: Index des aktuellen Elements
    • array: Der mit reduce aufgerufene Array
  • anfangsWert: (optional)

reduce() geht so vor, dass es den angegebenen Callback für jedes Array-Element einmal aufruft. Der Callback kann nun aus dem previousValue und dem currentValue einen neuen Wert bilden und zurückgegeben. Beim Callbackaufruf für das nächste Element ist dieser Rückgabewert dann der previousValue.

Das Ergebnis der Funktion ist der Wert, den der Callback bei seinem letzten Aufruf zurückgibt.

Veranschaulichung der Arbeitsweise von reduce()
class Array {
   reduce(callback, startvalue) {
      let i = 0;
      if (arguments.length < 2) {
         startvalue = this[0];
         i = 1;
      }
      for (; i < this.length; i++) {
         if (this.hasOwnPrpperty(i)) {
            startvalue = callback(startvalue, this[i], i, this);
         }
      }
      return startvalue;
   }  
}

Das Verhalten von reduce ändert sich, wenn man einen Anfangswert übergibt.

mit Übergabe eines Anfangswerts
reduce() verwendet den übergebenen Anfangswert als previousValue und beginnt ab dem ersten Array-Eintrag mit Callback-Aufrufen
  • Der Aufruf mit einem leeren Array liefert den Anfangswert zurück.
ohne Übergabe eines Anfangswerts
Dieser Aufruf ist sinnvoll, wenn der Callback für den ersten Arrayeintrag nichts anderes tun muss, als diesen Arrayeintrag unverändert zurückzugeben, z. B. wenn die Summe oder das Produkt aller Werte im Array gebildet werden soll.
reduce() verwendet bei dieser Aufrufvariante den ersten Array-Eintrag als Anfangswert und beginnt ab dem zweiten Array-Eintrag mit Callback-Aufrufen. Für diesen Fall ist zu beachten:
  • Der Aufruf mit einem leeren Array wirft einen TypeError
  • Der Aufruf mit einem Array, das genau einen Wert enthält, liefert diesen Wert zurück, ohne dass der Callback aufgerufen wurde.

Unter „erstem“ und „zweitem“ Eintrag des Arrays ist nicht zwingend die Indexpositionen 0 und 1 zu verstehen. Arrays können lückenhaft gefüllt sein, und reduce() nutzt nur die tatsächlich belegten Indexpositionen.

Einsatz von reduce() für eine Summenbildung
const array = [ 5, 9, 12, 7 ];
const summe = array.reduce(function(prev,akt) { return prev + akt; });
Die Callbackfunktion wird hier dreimal aufgerufen. Der erste Aufruf bekommt die Parameter prev=5 und akt=9
Einsatz von reduce() für eine komplexere Summenbildung
const datenpunkte = [ ['red', 1], ['green', 2], ['blue', 5] ];
const summe = datenpunkte.reduce((summe,punkt) => summe+punkt[1], 0);
In diesem Beispiel bestehen die Daten aus Unterarrays, und reduce() summiert den Wert des zweiten Elements in den Unterarrays auf. Ohne Übergabe eines Anfangswertes würde der erste Aufruf des Callbacks mit summe = [ 'red', 1 ] und punkt = [ 'green', 2] durchgeführt, und entweder müsste man dann zum Summieren temporäre Arrays bilden oder eine Fallunterscheidung machen. Durch den Anfangswert von 0 bleibt es bei Zahlen als Summe.
Einsatz von reduce() für eine komplexere Transformation
const columnDefinitions = [ 
        { field: 'Name', type: 'string' },
        { field: 'Vorname', type: 'string' },
        { field: 'Geburtsdatum', type: 'date' }
      ];
const columnIndex = columnDefinitions.reduce(function(prev, akt, index) {
   prev[akt.field] = index;
   return prev;
}, {});
Als Startwert wird ein leeres Objekt übergeben. Die Callbackfunktion wird genutzt, um pro Felddefinition in der Tabelle in diesem Objekt ein Property anzulegen, das den Index des Feldes in der Tabelle angibt. Nützlich, wenn man oft nach Feldpositionen suchen muss.

Die gezeigten Beispiele lassen sich durch Verwendung des for Statements deutlich performanter realisieren. Der Einsatz von reduce() wird dann interessanter, wenn der Inhalt der for-Schleife ohnehin ein Funktionsaufruf ist – oder sein muss, weil man Closures bilden will.

Siehe auch: JavaScript/Objekte/Math/max#Maximum_eines_Arrays

Weblinks