Article original : How to write your own map, filter and reduce functions in JavaScript
Par Hemand Nair
Un aperçu de la programmation fonctionnelle et des fonctions d'ordre supérieur en JavaScript.
_Photo par [Unsplash](https://unsplash.com/photos/pgSkeh0yl8o?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText" rel="noopener" target="_blank" title="">Christopher Robin Ebbinghaus sur <a href="https://unsplash.com/search/photos/javascript?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText" rel="noopener" target="blank" title=")
Chaque fois que j'entends parler de programmation fonctionnelle, la première chose qui me vient à l'esprit est les fonctions d'ordre supérieur. Pour ceux qui ne connaissent pas les fonctions d'ordre supérieur, voici ce que dit Wikipédia :
Une fonction d'ordre supérieur est une fonction qui fait au moins l'une des choses suivantes :
- Prend une ou plusieurs fonctions comme arguments,
- Retourne une fonction comme résultat.
Les fonctions d'ordre supérieur peuvent être mieux décrites par les fonctions map, filter et reduce. JavaScript possède par défaut sa propre implémentation de ces fonctions. Aujourd'hui, nous allons écrire nos propres fonctions map, filter et reduce.
Note : Gardez à l'esprit que ces implémentations des méthodes map, filter et reduce peuvent ne pas refléter les implémentations natives de leurs homologues JavaScript.
Map
D'après MDN :
La méthode
**map()**crée un nouveau tableau avec les résultats de l'appel d'une fonction fournie sur chaque élément du tableau appelant.
Cela semble assez simple. Maintenant, voyons le map() de JavaScript en action !
let arr = [1, 2, 3, 4, 5];
// passer une fonction à map
const squareArr = arr.map(num => num ** 2);
console.log(squareArr); // affiche [1, 4, 9, 16, 25]
Alors, que s'est-il passé ? Nous avons écrit une fonction qui retourne le carré d'un nombre et avons passé cette fonction comme argument à notre map(). Voyons étape par étape comment créer notre propre fonction map.
- Créer un tableau vide
mapArr. - Parcourir les éléments du tableau.
- Appeler la fonction
mapFuncavec l'élément actuel comme argument. - Pousser le résultat de la fonction
mapFuncdans le tableaumapArr. - Retourner le tableau
mapArraprès avoir parcouru tous les éléments.
Maintenant, écrivons notre implémentation de map()
// map prend un tableau et une fonction comme argument
function map(arr, mapFunc) { const mapArr = []; // tableau vide // boucle à travers le tableau for(let i=0;i<arr.length;i++) { const result = mapFunc(arr[i], i, arr); mapArr.push(result); } return mapArr;}
Maintenant, si vous appelez le nouveau map() dans le code de l'exemple précédent,
const squareArr2 = map(arr, num => num ** 2);
console.log(squareArr2); // affiche [1, 4, 9, 16, 25]
Plutôt cool, n'est-ce pas ? Passons à filter() ensuite.
Filter
D'après MDN :
La méthode
**filter()**crée un nouveau tableau avec tous les éléments qui passent le test implémenté par la fonction fournie.
Voyons un exemple :
let arr = [1, 2, 3, 4, 5];
// passer une fonction à filter
const oddArr = arr.filter(num => num % 2 === 0);
console.log(oddArr); // affiche [2, 4]
La fonction filter a pris une fonction qui retournera true si un nombre est pair. La méthode filter() « filtre » le tableau d'entrée en fonction de si l'élément est vrai ou faux. Passons étape par étape comment fonctionne filter().
- Créer un tableau vide
filterArr. - Parcourir les éléments du tableau.
- Appeler la fonction
filterFuncavec l'élément actuel comme argument. - Si le résultat est vrai, pousser l'élément dans le tableau
filterArr. - Retourner le tableau
filterArraprès avoir parcouru tous les éléments.
Il est temps d'écrire notre propre filter()
// filter prend un tableau et une fonction comme argument
function filter(arr, filterFunc) { const filterArr = []; // tableau vide // boucle à travers le tableau for(let i=0;i<arr.length;i++) { const result = filterFunc(arr[i], i, arr); // pousser l'élément actuel si le résultat est vrai if(result) filterArr.push(arr[i]); } return filterArr;}
Voyons si notre nouveau filter() fonctionne avec l'exemple précédent :
const oddArr2 = filter(arr, num => num % 2 === 0);
console.log(oddArr2); // affiche [2, 4]
Propre ! J'ai gardé le meilleur et le plus difficile pour la fin. Passons à reduce() ensuite.
Reduce
D'après MDN :
La méthode
**reduce()**exécute une fonction reducer (que vous fournissez) sur chaque membre du tableau, résultant en une seule valeur de sortie.
Cela a du sens ? Non ? Voici un exemple pour vous aider à comprendre :
let arr = [1, 2, 3, 4];
const sumReducer = (accumulator, currentValue) => accumulator + currentValue;
// 1 + 2 + 3 + 4
const sum = arr.reduce(sumReducer);
console.log(sum);
// affiche 10
// 5 + 1 + 2 + 3 + 4
const sum2 = arr.reduce(sumReducer, 5);
console.log(sum2);
// affiche 15
Commencez-vous à avoir une idée ? Clarifions. Avant de creuser trop profondément dans la méthode reduce(), vous pourriez avoir besoin de vous familiariser avec la fonction reducer.
Si vous avez utilisé redux dans le passé, vous pourriez avoir une idée de ce qu'est une fonction reducer. Dans l'exemple ci-dessus, la fonction reducer est écrite comme la somme entre l'accumulateur et la valeur actuelle. Lorsque vous passez la fonction reducer à la méthode reduce(), elle parcourra chaque nombre dans le tableau et l'ajoutera à l'accumulateur (0 au début), qui devient lui-même le nouvel accumulateur pour l'itération suivante. Cela continue jusqu'à la fin du tableau et retourne l'accumulateur comme résultat.
Si je devais afficher la valeur de l'accumulateur à chaque étape pour l'exemple ci-dessus, ce serait comme ceci :
- Avant le début de l'itération,
accumulator = 0 - 1ère itération,
accumulator += 1; // accumulator = 1 - 2ème itération,
accumulator += 2; // accumulator = 3 - 3ème itération,
accumulator += 3; // accumulator = 6 - 4ème itération,
accumulator += 4; // accumulator = 10
La valeur retournée par votre fonction reducer est assignée à l'accumulateur, dont la valeur est mémorisée à travers chaque itération du tableau. Elle devient finalement la valeur résultante unique et finale.
Si vous êtes encore bloqué à un moment donné, essayez d'écrire quelques opérations avec la méthode reduce() intégrée. Dès que vous vous sentez prêt, passez aux étapes suivantes pour implémenter votre reduce() personnalisé :
- Initialiser la variable
accumulatoravec 0 ou la valeurinitialValuede l'argumentreduce(). - Parcourir les éléments du tableau.
- Appeler la fonction
reduceravec l'accumulatoret l'élément actuel comme arguments. - Retourner
accumulatoraprès avoir parcouru tous les éléments.
Très bien, il est temps de coder.
// reducer prend un tableau, reducer() et initialValue comme argument
function reduce(arr, reducer, initialValue) { let accumulator = initialValue === undefined ? 0 : initialValue // boucle à travers le tableau for(let i=0;i<arr.length;i++) accumulator = reducer(accumulator, arr[i], i, arr); return accumulator;}
Eh bien, c'était plus facile que prévu. Voyons si cela fonctionne.
const sum = reduce(arr, sumReducer);
console.log(sum); // affiche 10
const sum2 = reduce(arr, sumReducer, 5);
console.log(sum2);// affiche 15
Fonctionne à merveille !
C'est tout :)
Laissez un commentaire ci-dessous si vous avez des questions.