Etienne Talbot

Volgen

Jan 29, 2018 · 7 min lezen

Als je begint in JavaScript, misschien heb je niet gehoord van de .map(), .reduce(), en .filter()., Voor mij, het duurde een tijdje als ik moest Internet Explorer ondersteunen 8 tot een paar jaar geleden. Maar als je niet nodig om compatibel te zijn met deze zeer oude browser, je moet vertrouwd raken met deze methoden.

merk op dat dit artikel waarschijnlijk van toepassing is op elke andere programmeertaal die u gebruikt, aangezien dit concepten zijn die in veel andere talen bestaan.

laat me uitleggen hoe het werkt met een eenvoudig voorbeeld. Stel dat je een array hebt ontvangen die meerdere objecten bevat – elk die een persoon vertegenwoordigt., Wat je uiteindelijk echt nodig hebt, is een array die alleen de id van elke persoon bevat.

laten we vergelijken!

met .forEach():

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

merk op hoe u vooraf een lege array moet aanmaken? Laten we eens kijken hoe het eruit ziet bij gebruik van .map():

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

We kunnen zelfs beknopter zijn met arrow-functies (vereist ES6-ondersteuning, Babel of TypeScript)

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

dus hoe werkt .map() werk?, In principe neemt dit 2 argumenten, een callback en een optionele context (zal worden beschouwd als this in de callback) die ik niet gebruikte in het vorige voorbeeld. De callback draait voor elke waarde in de array en retourneert elke nieuwe waarde in de resulterende array.

Houd er rekening mee dat de resulterende array altijd dezelfde lengte zal hebben als de originele array.

.reduce ()

net als .map(), .reduce() draait ook een callback voor elk element van een array., Wat hier anders is, is dat reduce het resultaat van deze callback (de accumulator) van het ene array-element naar het andere doorgeeft.

de accumulator kan vrijwel alles zijn (integer, string, object, etc.) en moet worden geïnstalleerd of doorgegeven wanneer .reduce()wordt aangeroepen.

tijd voor een voorbeeld! Stel dat je een array hebt met deze piloten en hun respectievelijke jaren ervaring:

We moeten de totale jaren ervaring van alle van hen kennen., Met .reduce() is het vrij eenvoudig:

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

merk op dat ik de startwaarde als 0 heb ingesteld. Ik had ook een bestaande variabele kunnen gebruiken indien nodig. Na het uitvoeren van de callback voor elk element van de array, zal reduce de uiteindelijke waarde van onze accumulator retourneren (in ons geval: 82).

laten we eens kijken hoe dit kan worden ingekort met ES6 ‘ s pijl functies:

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

laten we nu zeggen dat Ik wil vinden welke pilot de meest ervaren is., Daarvoor kan ik ook reduce gebruiken:

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

Ik heb mijn accumulator oldestgenoemd. Mijn callback vergelijkt de accumulator met elke piloot. Als een piloot meer jaren ervaring heeft dan oldest, dan wordt die piloot de nieuwe oldest , dus dat is degene die ik retourneer.

zoals u kunt zien, is het gebruik van .reduce() een eenvoudige manier om een enkele waarde of object uit een array te genereren.

.filter ()

Wat als je een array hebt, maar alleen enkele elementen erin wilt?, Dat is waar .filter() in komt!

Hier zijn onze gegevens:

stel dat we nu twee arrays willen: een voor rebel pilots, de andere voor imperials. Met .filter() kan het niet eenvoudiger!

dat is het! En het is nog korter met arrow functies:

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

in principe, als de callback functie waar retourneert, zal het huidige element in de resulterende array zijn. Als het vals is, is het niet waar.

combineren .kaart(), .reduce (), en .,filter ()

omdat alle drie arrays aangeroepen worden en omdat .map() en .filter() beide arrays retourneren, kunnen we onze calls eenvoudig chaineren.

laten we een ander voorbeeld bekijken. Hier zijn onze gegevens:

ons doel: krijg alleen de totale score van force-gebruikers. Laten we het stap voor stap doen!

eerst moeten we het personeel filteren dat de kracht niet kan gebruiken:

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

hiermee hebben we nog 3 elementen over in onze resulterende array. We moeten nu een array maken met de totale score van elke Jedi.,

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

en laten we reduce gebruiken om het totaal te krijgen:

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

en nu is hier het leuke gedeelte… we kunnen dit alles chaineren om te krijgen wat we willen in een enkele regel:

en kijk hoe mooi het is met pijl functies:

Boom! 💥

opmerking: in mijn vorige voorbeeld waren .map() en .filter() niet eens nodig. We kunnen gemakkelijk hetzelfde resultaat bereiken met alleen .reduce(). Ik liet ze daar voor dit voorbeeld., Kun je raden hoe we alleen .reduce() konden behouden en hetzelfde resultaat konden krijgen met één regel code? Zie de oplossing op CodePen

waarom niet gebruiken .forEach ()?

Ik gebruikte for overal lussen in plaats van .map(), .reduce(), en .filter(). Maar een paar jaar geleden begon ik veel meer te werken met data die afkomstig waren van een API. Daar begon ik de voordelen te zien van het achterlaten van .forEach.,

opmaak

geef aan dat u een lijst met personen moet weergeven, met hun naam en functie.

var data = 

de API geeft je de bovenstaande gegevens, maar je hebt alleen de titel en de achternaam van elke persoon nodig… je moet de gegevens formatteren. Uw app moet echter ook een enkele weergave voor elke persoon hebben, dus u moet een functie voor gegevensopmaak schrijven die zowel in een lijstweergave als in een enkele weergave werkt.,

dat betekent dat u de .forEach lus niet in uw opmaakfunctie kunt hebben, anders moet u uw enkel element in een array wikkelen voordat u het aan de functie doorgeeft om het te laten werken, zoals:

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

dus uw lus moet de aanroep van de functie afbreken, zoals dit:

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

maar .forEach() geeft niets terug. Dat betekent dat je de resultaten in een vooraf bepaalde reeks moet duwen.,

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

hierdoor heeft u 2 Functies: uw formatElement() functie en uw functie die de resultaten in uw array pusht.

Waarom 2 functies hebben als je er maar één kunt hebben?

var results = data.map(formatElement);

testen is eenvoudiger

Als u unit tests voor uw code schrijft, zult u het eenvoudiger vinden om de functies te testen die u aanroept met .map(), .reduce(), of .filter().

het enige wat u hoeft te doen is inkomende gegevens voor de functie op te geven en te verwachten dat er een resultaat uitkomt., Eigenlijk “wat komt er uit als dit wordt aangenomen?”. Minder manipulatie, minder beforeEach()s en afterEach()s. Het is eenvoudig, eenvoudig testen.

probeer het!

als je dat artikel leuk vond en meer wilt weten over array methoden, bekijk dan mijn artikel over het gebruik van .some() en .find() In JavaScript.

blijf coderen!

Articles

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *