Etienne Talbot

Suivre

Jan 29, 2018 · 7 min en lecture

Si vous êtes débutant en JavaScript, peut-être que vous n’avez pas entendu parler de .map(), .reduce() et .filter()., Pour moi, cela a pris un certain temps car je devais supporter Internet Explorer 8 jusqu’à il y a quelques années. Mais si vous n’avez pas besoin d’être compatible avec ce très vieux navigateur, vous devez vous familiariser avec ces méthodes.

notez que cet article s’applique très probablement à tout autre langage de programmation que vous utilisez, car ce sont des concepts qui existent dans de nombreux autres langages.

Permettez-moi d’expliquer comment cela fonctionne avec un exemple simple. Supposons que vous ayez reçu un tableau contenant plusieurs objets-chacun représentant une personne., La chose dont vous avez vraiment besoin à la fin, cependant, est un tableau contenant uniquement l’id de chaque personne.

nous allons comparer!

.forEach():

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

Remarquez comment vous vous devez créer un tableau vide à l’avance? Voyons à quoi cela ressemble lorsque vous utilisez .map():

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

Nous pouvons même être plus concis avec les fonctions arrow (nécessite le support ES6, Babel ou TypeScript)

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

alors, comment .map() travail?, Fondamentalement, is prend 2 arguments, un rappel et un contexte facultatif (sera considéré comme this dans le rappel) que je n’ai pas utilisé dans l’exemple précédent. Le rappel s’exécute pour chaque valeur du tableau et renvoie chaque nouvelle valeur du tableau résultant.

Gardez à l’esprit que le tableau résultant sera toujours de la même longueur que le tableau d’origine.

.réduire()

comme .map(), .reduce() exécute également un rappel pour chaque élément d’un tableau., Ce qui est différent ici, c’est que reduce transmet le résultat de ce rappel (l’accumulateur) d’un élément de tableau à l’autre.

l’accumulateur peut être à peu près n’importe quoi (entier, chaîne, objet, etc.) et doit être instancié ou passé lors de l’appel de .reduce().

de Temps pour un exemple! Disons que vous avez un tableau avec ces pilotes et leurs années d’expérience:

Nous avons besoin de savoir le nombre d’années d’expérience de tous., Avec des .reduce(), c’est assez simple:

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

Notez que j’ai mis la valeur de départ 0. J’aurais également pu utiliser une variable existante si nécessaire. Après avoir exécuté le rappel pour chaque élément du tableau, reduce renverra la valeur finale de notre accumulateur (dans notre cas: 82).

voyons comment cela peut être raccourci avec les fonctions arrow D’ES6:

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

maintenant, disons que je veux trouver quel pilote est le plus expérimenté., Pour cela, je peux utiliser de réduire ainsi:

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

j’ai appelé mon accumulateur oldest. Mon rappel compare l’accumulateur à chaque pilote. Si un pilote a plus d’années d’expérience que oldest, alors ce pilote devient le nouveau oldest donc c’est celui que je retourne.

comme vous pouvez le voir, Utiliser.reduce() est un moyen facile de générer une seule valeur ou un seul objet à partir d’un tableau.

.filtre()

Que faire si vous avez un tableau, mais qui ne veulent quelques-uns des éléments qu’il contient?, C’est là que .filter() entre en jeu!

Voici nos données:

Disons que nous voulons deux tableaux aujourd’hui: l’un pour les rebelles, les pilotes, l’autre pour les impériaux. Avec .filter() cela ne pourrait pas être plus facile!

C’est elle! Et c’est encore plus court avec les fonctions de flèche:

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

fondamentalement, si la fonction de rappel renvoie true, l’élément actuel sera dans le tableau résultant. S’il renvoie false, ce ne sera pas le cas.

combinaison .cartographie(), .réduire(), et .,filter ()

puisque tous les trois sont appelés sur des tableaux et que.map() Et.filter() renvoient tous deux des tableaux, nous pouvons facilement enchaîner nos appels.

voyons maintenant un autre exemple. Voici nos données:

Notre objectif: obtenir le score total de forcer les utilisateurs seulement. Nous allons faire étape par étape!

Tout d’abord, nous devons filtrer le personnel qui ne peut pas utiliser la force:

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

avec cela, il nous reste 3 éléments dans notre tableau résultant. Nous devons maintenant créer un tableau contenant le score total de chaque Jedi.,

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

Et nous allons utiliser les réduire pour obtenir le total:

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

Et maintenant, voici la partie amusante… nous pouvons chaîne tout cela pour obtenir ce que nous voulons en une seule ligne:

Et regardez à quelle jolie c’est avec une flèche fonctions:

Boum! 💥

Note: Dans mon exemple précédent, .map() et .filter() n’étaient même pas nécessaires. On pourrait facilement obtenir le même résultat avec seulement .reduce(). Je les ai laissés là – dedans pour cet exemple., Pouvez-vous deviner comment nous pourrions seulement garder .reduce() et obtenir le même résultat avec une ligne de code? Voir la solution sur CodePen

pourquoi ne pas utiliser .forEach ()?

j’ai l’habitude d’utiliser des for boucles partout au lieu de .map(), .reduce() et .filter(). Mais il y a quelques années, j’ai commencé à travailler beaucoup plus avec des données provenant d’une API. C’est là que j’ai commencé à voir les avantages de laisser .forEach derrière.,

formatage

dites que vous devez afficher une liste de personnes, avec leur nom et leur titre de poste.

var data = 

L’API vous donne les données ci-dessus, mais vous n’avez besoin que du titre et du nom de famille de chaque personne-vous devez formater les données. Cependant, votre application doit également avoir une vue unique pour chaque personne, vous devez donc écrire une fonction de formatage des données qui fonctionne à la fois dans une vue de liste et dans une vue unique.,

cela signifie que vous ne pouvez pas avoir la boucle .forEach à l’intérieur de votre fonction de formatage, sinon vous devrez envelopper votre seul élément dans un tableau avant de le passer à la fonction juste pour le faire fonctionner, comme ceci:

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

donc votre boucle doit envelopper= »4ac89cc1d5″>

mais.forEach()ne renvoie rien. Cela signifie que vous devez pousser les résultats dans un tableau prédéterminé.,

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

Comme un résultat, vous avez 2 fonctions: ton formatElement() fonction et de votre fonction qui pousse les résultats dans votre tableau.

Pourquoi avoir 2 fonctions quand vous pouvez avoir un seul?

var results = data.map(formatElement);

Test est plus facile

Si vous écrivez des tests unitaires pour votre code, vous trouverez qu’il est plus simple pour tester les fonctions d’appel avec des .map(), .reduce() ou .filter().

Tout ce que vous avez à faire est de fournir des données entrantes pour la fonction et d’attendre un résultat., Fondamentalement,  » qu’est-ce qui sort si cela est passé?”. Moins de manipulation, moins de beforeEach()s et afterEach()S. c’est un test simple et simple.

essayez-le!

Si vous avez aimé cet article et que vous voulez en savoir plus les méthodes de tableau, consultez mon article sur la façon d’utiliser .some() et .find() en JavaScript.

Garder le codage!

Articles

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *