Etienne Talbot

Folgen

Jan 29, 2018 · 7 min lesen

Wenn Sie mit JavaScript beginnen, haben Sie vielleicht noch nichts von.map(),.reduce() und .filter() div>., Für mich hat es eine Weile gedauert, da ich Internet Explorer 8 bis vor ein paar Jahren unterstützen musste. Wenn Sie jedoch nicht mit diesem sehr alten Browser kompatibel sein müssen, müssen Sie sich mit diesen Methoden vertraut machen.

Beachten Sie, dass dieser Artikel höchstwahrscheinlich für jede andere Programmiersprache gilt, die Sie verwenden, da dies Konzepte sind, die in vielen anderen Sprachen existieren.

Lassen Sie mich erklären, wie es mit einem einfachen Beispiel funktioniert. Angenommen, Sie haben ein Array erhalten, das mehrere Objekte enthält – jedes repräsentiert eine Person., Das, was Sie am Ende wirklich brauchen, ist jedoch ein Array, das nur die ID jeder Person enthält.

Vergleichen wir!

Mit .forEach():

var officersIds = ;officers.forEach(function (officer) {
officersIds.push(officer.id);
});

Beachten Sie, wie Sie vorher ein leeres Array erstellen müssen? Mal sehen, wie es aussieht, wenn .map():

var officersIds = officers.map(function (officer) {
return officer.id
});

Wir können sogar prägnanter mit Pfeilfunktionen sein (erfordert ES6-Unterstützung, Babel oder TypoSkript)

const officersIds = officers.map(officer => officer.id);

Wie funktioniert also .map()?, Grundsätzlich benötigt es 2 Argumente, einen Rückruf und einen optionalen Kontext (wird im Rückruf als this), den ich im vorherigen Beispiel nicht verwendet habe. Der Rückruf wird für jeden Wert im Array ausgeführt und gibt jeden neuen Wert im resultierenden Array zurück.

Beachten Sie, dass das resultierende Array immer die gleiche Länge wie das ursprüngliche Array hat.

.reduce ()

Genau wie .map() führt .reduce() auch einen Rückruf für jedes Element eines Arrays aus., Anders ist hier, dass reduce das Ergebnis dieses Rückrufs (den Akkumulator) von einem Array-Element zum anderen übergibt.

Der Akkumulator kann so ziemlich alles sein (Ganzzahl, Zeichenfolge, Objekt usw.) und muss beim Aufruf von .reduce()instanziiert oder übergeben werden.

Zeit für ein Beispiel! Angenommen, Sie haben ein Array mit diesen Piloten und ihrer jeweiligen jahrelangen Erfahrung:

Wir müssen die Gesamterfahrung aller Piloten kennen., Mit .reduce() ist es ziemlich einfach:

var totalYears = pilots.reduce(function (accumulator, pilot) {
return accumulator + pilot.years;
}, 0);

Beachten Sie, dass ich den Startwert auf 0 gesetzt habe. Ich hätte bei Bedarf auch eine vorhandene Variable verwenden können. Nach dem Ausführen des Rückrufs für jedes Element des Arrays gibt reduce den endgültigen Wert unseres Akkumulators zurück (in unserem Fall: 82).

Lassen Sie uns sehen, wie dies mit den Pfeilfunktionen von ES6 verkürzt werden kann:

const totalYears = pilots.reduce((acc, pilot) => acc + pilot.years, 0);

Angenommen, ich möchte herausfinden, welcher Pilot der erfahrenste ist., Dafür kann ich auch reduce:

var mostExpPilot = pilots.reduce(function (oldest, pilot) {
return (oldest.years || 0) > pilot.years ? oldest : pilot;
}, {});

Ich habe meinen Akkumulator oldest. Mein Rückruf vergleicht den Akkumulator mit jedem Piloten. Wenn ein Pilot mehr Jahre Erfahrung hat als oldest, dann wird dieser Pilot der neue oldest Das ist der, den ich zurückgebe.

Wie Sie sehen, ist die Verwendung von .reduce() eine einfache Möglichkeit, einen einzelnen Wert oder ein einzelnes Objekt aus einem Array zu generieren.

.filter ()

Was ist, wenn Sie ein Array haben, aber nur einige der Elemente darin haben möchten?, Hier kommt .filter() ins Spiel!

Hier sind unsere Daten:

Sagen wir, wir wollen jetzt zwei Arrays: eines für Rebellenpiloten, das andere für Imperiale. Mit .filter() könnte es nicht einfacher sein!

Das war ‚ s! Und es ist noch kürzer mit Pfeilfunktionen:

const rebels = pilots.filter(pilot => pilot.faction === "Rebels");
const empire = pilots.filter(pilot => pilot.faction === "Empire");

Wenn die Rückruffunktion true zurückgibt, befindet sich das aktuelle Element im resultierenden Array. Wenn es false zurückgibt, wird es nicht sein.

Kombinieren .anzeigen(), .reduzieren (), und .,filter ()

Da alle drei Arrays aufgerufen werden und .map() und .filter() beide Arrays zurückgeben, können wir unsere Aufrufe einfach verketten.

Schauen wir uns ein anderes Beispiel an. Hier sind unsere Daten:

Unser Ziel: Erhalten Sie nur die Gesamtpunktzahl der Force-Benutzer. Lass es uns Schritt für Schritt machen!

Zuerst müssen wir das Personal herausfiltern, das die Kraft nicht einsetzen kann:

var jediPersonnel = personnel.filter(function (person) {
return person.isForceUser;
});// Result: (Luke, Ezra and Caleb)

Damit haben wir noch 3 Elemente in unserem resultierenden Array. Wir müssen jetzt ein Array erstellen, das die Gesamtpunktzahl jedes Jedi enthält.,

var jediScores = jediPersonnel.map(function (jedi) {
return jedi.pilotingScore + jedi.shootingScore;
});// Result:

Und verwenden wir reduce, um die Summe zu erhalten:

var totalJediScore = jediScores.reduce(function (acc, score) {
return acc + score;
}, 0);// Result: 420

Und jetzt ist hier der lustige Teil… wir können all dies verketten, um das zu bekommen, was wir wollen in einer einzigen Zeile:

Und schauen, wie hübsch es mit Pfeilfunktionen ist:

Boom! 💥

Hinweis: In meinem vorherigen Beispiel waren .map() und .filter() nicht einmal notwendig. Wir könnten leicht das gleiche Ergebnis mit nur .reduce(). Ich habe sie wegen dieses Beispiels dort gelassen., Können Sie sich vorstellen, wie wir nur .reduce() .reduce() und dasselbe Ergebnis mit einer Codezeile erhalten können? Finden Sie die Lösung auf CodePen

Warum nicht .forEach()?

Ich habe for Schleifen überall anstelle von .map(), .reduce() und .filter()verwendet. Aber vor ein paar Jahren habe ich angefangen, viel mehr mit Daten zu arbeiten, die von einer API stammen. Hier begann ich die Vorteile zu sehen, .forEach zurückzulassen.,

Formatierung

Angenommen, Sie müssen eine Liste von Personen mit ihrem Namen und ihrer Berufsbezeichnung anzeigen.

var data = 

Die API gibt Ihnen die obigen Daten, aber Sie benötigen nur den Titel und den Nachnamen jeder Person… Sie müssen die Daten formatieren. Ihre App muss jedoch auch eine einzelne Ansicht für jede Person haben, sodass Sie eine Datenformatierungsfunktion schreiben müssen, die sowohl in einer Listenansicht als auch in einer einzelnen Ansicht funktioniert.,

Das bedeutet, dass Sie die .forEach – Schleife nicht in Ihrer Formatierungsfunktion haben können, oder Sie müssten Ihr einzelnes Element in ein Array einschließen, bevor Sie es an die Funktion übergeben, nur damit es funktioniert, wie folgt:

var result = formatElement();
// Yeah... that's not right at all

Damit Ihre Schleife den Aufruf der Funktion wie folgt umschließen muss:

data.forEach(function (element) {
var formatted = formatElement(element);
// But what then....
});

gibt nichts zurück. Das heißt, Sie müssen die Ergebnisse in ein vorbestimmtes Array verschieben.,

var results = ;data.forEach(function (element) {
var formatted = formatElement(element);
results.push(formatted);
});

Als Ergebnis haben Sie 2 Funktionen: Ihre formatElement() Funktion und Ihre Funktion, die die Ergebnisse in Ihrem Array pusht.

Warum haben Sie 2 Funktionen, wenn Sie nur eine haben können?

var results = data.map(formatElement);

Testen ist einfacher

Wenn Sie Komponententests für Ihren Code schreiben, ist es einfacher, die Funktionen zu testen, die Sie mit .map(), .reduce() oder .filter()aufrufen.

Sie müssen lediglich eingehende Daten für die Funktion bereitstellen und ein Ergebnis erwarten., Grundsätzlich „Was kommt heraus, wenn dies bestanden wird?”. Weniger Manipulation, weniger beforeEach()s und afterEach()s. Es ist unkompliziert, einfache Tests.

Probier es aus!

Wenn Ihnen dieser Artikel gefallen hat und Sie mehr über Array-Methoden erfahren möchten, lesen Sie meinen Artikel zur Verwendung von .some() und .find() in JavaScript.

Codieren Sie weiter!

Articles

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.