JavaScript/Objekte/Array/reduce
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.
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 Elementindex
: Index des aktuellen Elementsarray
: Der mitreduce
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.
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 alspreviousValue
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.
- Der Aufruf mit einem leeren Array wirft einen
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.
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
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.
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.
→ JavaScript/Objekte/Math/max#Maximum_eines_Arrays
Weblinks
- ECMAScript: array.prototype.reduce
- MDN: Array.prototype.reduce()