Cinq façons intéressantes d'utiliser Array.reduce () (et une façon ennuyeuse)

Bonjour, Habr! Je vous présente la traduction de l'article "Cinq façons intéressantes d'utiliser Array.reduce () (et une façon ennuyeuse)" de Chris Ferdinandi.


De toutes les méthodes modernes de travail avec les tableaux, le plus difficile de tous que j'ai dû utiliser était Array.reduce ().


À première vue, cela semble être une méthode simple et ennuyeuse qui ne fait pas grand-chose. Mais, malgré son apparence modeste, Array.reduce () est un ajout puissant et flexible à votre ensemble d'outils de développement.


Aujourd'hui, regardons quelques choses intéressantes que vous pouvez faire avec Array.reduce ().


Fonctionnement de Array.reduce ()


La plupart des méthodes de tableau modernes renvoient un nouveau tableau. La méthode Array.reduce () est un peu plus flexible. Il peut tout retourner. Son but est de prendre un tableau et de compresser son contenu en une seule valeur.


Cette valeur peut être un nombre, une chaîne ou même un objet ou un nouveau tableau. C'est la partie qui m'a toujours dérouté - je n'ai pas compris à quel point c'est flexible!


Syntaxe


Array.reduce () prend deux arguments: la méthode de rappel, exécutée pour lancer chaque élément du tableau, et la valeur initiale initialValue.


Le rappel prend également deux arguments: l'accumulateur, qui est la valeur combinée actuelle, et l'élément actuel dans la boucle currentValue. Tout ce que vous retournez est utilisé comme accumulateur pour l'élément suivant dans la boucle. La toute première boucle utilise à la place la valeur initiale.


var myNewArray = [].reduce(function (accumulator, current) { return accumulator;}, starting); }, starting); 

Regardons quelques exemples.


 var myNewArray = [].reduce(function (accumulator, current) { return accumulator;}, starting); 

1. Sommation des nombres


Supposons que vous ayez un tableau de nombres que vous souhaitez additionner. En utilisant Array.forEach (), nous pouvons faire quelque chose comme ceci:


 var total = 0; [1, 2, 3].forEach(function (num) { total += num; }); 

Ceci est un exemple de cliché pour l'utilisation de Array.reduce (). Le mot «accumulateur» prête à confusion, donc dans cet exemple, nous l'appellerons «somme» parce que c'est ce qu'il est intrinsèquement.


 var total = [1, 2, 3].reduce(function (sum, current) { return sum + current; }, 0);    0    . 

Dans le rappel, nous ajoutons la valeur actuelle au montant qui a une valeur initiale de 0 au premier cycle, puis 1 (valeur initiale 0 plus valeur d'élément 1), puis 3 (valeur totale 1 plus valeur d'élément 2) et ainsi de suite.
Un exemple.


2.Une alternative à la combinaison des méthodes de tableau Array.map () et Array.filter () en une seule étape


Imaginez qu'il y ait beaucoup de sorciers à Poudlard.


 var wizards = [ { name: 'Harry Potter', house: 'Gryfindor' }, { name: 'Cedric Diggory', house: 'Hufflepuff' }, { name: 'Tonks', house: 'Hufflepuff' }, { name: 'Ronald Weasley', house: 'Gryfindor' }, { name: 'Hermione Granger', house: 'Gryfindor' }]; 

Nous voulons créer un nouveau tableau qui ne contiendra que les noms des maîtres de Poufsouffle. Une façon de procéder consiste à utiliser la méthode Array.filter () pour récupérer uniquement les assistants qui ont une propriété Poufsouffle à la maison. Ensuite, nous utilisons la méthode Array.map () pour créer un nouveau tableau contenant uniquement la propriété name pour les maîtres restants.


 //      var hufflepuff = wizards.filter(function (wizard) { return wizard.house === 'Hufflepuff'; }).map(function (wizard) { return wizard.name; }); 

En utilisant la méthode Array.reduce (), vous pouvez obtenir le même tableau en un seul passage, ce qui améliorera nos performances. Nous passons un tableau vide ([]) comme valeur initiale. À chaque passage, nous vérifions si wizard.house est un Poufsouffle. Si c'est le cas, envoyez-le à newArr (notre accumulateur dans cet exemple). Sinon, ne faites rien.


Dans tous les cas, retournez newArr pour récupérer l'accumulateur lors de la prochaine passe.


 //      var hufflepuff = wizards.reduce(function (newArr, wizard) { if (wizard.house === 'Hufflepuff') { newArr.push(wizard.name); } return newArr; }, []); 

Un exemple.


3.Créer un balisage à partir d'un tableau


Et si, au lieu de créer un tableau de noms, nous voulions créer une liste non ordonnée de maîtres dans Poufsouffle? Au lieu d'un tableau vide dans Array.reduce () comme valeur initiale, passez une chaîne vide ('') et appelez-la html.


Si wizard.house est égal à Poufsouffle, nous combinons notre chaîne html avec wizard.name enveloppé dans les éléments de liste d'ouverture et de fermeture (li). Retournez ensuite HTML comme accumulateur dans la boucle suivante.


 //      var hufflepuffList = wizards.reduce(function (html, wizard) { if (wizard.house === 'Hufflepuff') { html += '<li>' + wizard.name + '</li>'; } return html; }, ''); 

Ajoutez l'élément de liste d'ouverture et de fermeture non ordonné avant et après Array.reduce (). Vous êtes maintenant prêt à ajouter du balisage au DOM.


 //      var hufflepuffList = '<ul>' + wizards.reduce(function (html, wizard) { if (wizard.house === 'Hufflepuff') { html += '<li>' + wizard.name + '</li>'; } return html; }, '') + '</ul>'; 

Un exemple.


4. Regroupement d'éléments similaires dans un tableau


La bibliothèque lodash a une méthode groupBy () qui prend une collection d'éléments comme un tableau et les regroupe dans un objet en fonction de certains critères.


Disons que nous avons besoin d'un tableau de nombres.


Si nous voulons regrouper tous les éléments en nombres par leur valeur entière, cela doit être fait en utilisant lodash.


 var numbers = [6.1, 4.2, 6.3]; // returns {'4': [4.2], '6': [6.1, 6.3]} _.groupBy(numbers, Math.floor); 

S'il y a un tableau de mots et que vous devez regrouper les éléments dans les mots par leur longueur, nous le ferions.


 var words = ['one', 'two', 'three']; // returns {'3': ['one', 'two'], '5': ['three']} _.groupBy(words, 'length'); 

Création d'une fonction groupBy () à l'aide de Array.reduce ()


Vous pouvez recréer la même fonctionnalité à l'aide de la méthode Array.reduce ().


Nous créons une fonction auxiliaire groupBy (), qui prend un tableau et des critères de tri comme arguments. Dans groupBy (), nous allons exécuter Array.reduce () pour notre tableau, en passant un objet vide ({}) comme point de départ et en retournant le résultat.


 var groupBy = function (arr, criteria) { return arr.reduce(function (obj, item) { // Some code will go here... }, {}); }; 

Dans Array.reduce (), nous appelons la fonction de rappel pour vérifier si le critère est une fonction appliquée à un élément ou une propriété d'un élément. Ensuite, nous obtenons sa valeur de l'élément courant.


Si l'objet n'a pas encore de propriété avec cette valeur, créez-la [propriété] et affectez un tableau vide comme valeur. Enfin, ajoutez un élément à cette propriété et renvoyez l'objet en tant qu'accumulateur pour le cycle suivant.


 var groupBy = function (arr, criteria) { return arr.reduce(function (obj, item) { //   ,        //  var key = typeof criteria === 'function' ? criteria(item) : item[criteria]; //    ,  . if (!obj.hasOwnProperty(key)) { obj[key] = []; } //     obj[key].push(item); //      return obj; }, {});}; 

Démonstration d'une fonction d'aide terminée.


Un merci spécial à Tom Bremer pour son aide. Cette fonction d'aide et bien plus peut être trouvée dans le Vanilla JS Toolkit .


5. Combinaison de données de deux sources dans un tableau


Rappelez-vous notre liste de sorciers.


 var wizards = [ { name: 'Harry Potter', house: 'Gryfindor' }, { name: 'Cedric Diggory', house: 'Hufflepuff' }, { name: 'Tonks', house: 'Hufflepuff' }, { name: 'Ronald Weasley', house: 'Gryfindor' }, { name: 'Hermione Granger', house: 'Gryfindor' }]; 

Et s'il y avait un ensemble de données différent - un objet avec une maison et des points gagnés par chaque magicien.


 var points = { HarryPotter: 500, CedricDiggory: 750, RonaldWeasley: 100, HermioneGranger: 1270 }; 

Imaginez que nous voulons combiner les deux ensembles de données dans un tableau avec le nombre de points ajoutés aux données de chaque assistant dans le tableau des assistants. Comment faire


La méthode Array.reduce () est parfaite pour cela!


 var wizardsWithPoints = wizards.reduce(function (arr, wizard) { //     points,     // var key = wizard.name.replace(' ', ' '); //     ,  , //   0. if (points[key]) { wizard.points = points[key]; } else { wizard.points = 0; } //   wizard   . arr.push(wizard); //  . return arr; }, []); 

Un exemple de combinaison de données de deux sources dans un tableau .


6. Combinaison de données de deux sources dans un objet


Et si, à la place, il était nécessaire de combiner les deux sources de données en un objet dans lequel le nom de chaque assistant est la clé, et leur maison et leurs lunettes sont des propriétés? Encore une fois, la méthode Array.reduce () est parfaite pour cela.


 var wizardsAsAnObject = wizards.reduce(function (obj, wizard) { //      points,     // var key = wizard.name.replace(' ', ' '); //     ,  , //   0. if (points[key]) { wizard.points = points[key]; } else { wizard.points = 0; } //   name delete wizard.name; //   wizard    obj[key] = wizard; //   return obj; }, {}); 

Un exemple de combinaison de données de deux sources dans un objet .


Dois-je utiliser Array.reduce ()?


La méthode Array.reduce () est passée de vide de sens à ma méthode JavaScript préférée. Cela vaut-il la peine de l'utiliser? Et quand?


La méthode Array.reduce () prend en charge un navigateur fantastique. Il fonctionne dans tous les navigateurs modernes et dans IE9. Il a longtemps été pris en charge par les navigateurs mobiles. Si vous en avez besoin de plus, vous pouvez ajouter un polyfill pour renvoyer le support dans IE6.


Le problème le plus grave peut être que Array.reduce () prête à confusion pour les personnes qui ne l'ont jamais rencontré [méthode] auparavant. La combinaison des méthodes Array.filter () avec Array.map () est plus lente et implique des étapes supplémentaires, mais est plus facile à lire. Les noms des méthodes indiquent ce qu'elles doivent faire.


Comme déjà mentionné, la méthode Array.reduce (), en général, simplifie les choses plus complexes. Un bon exemple est la fonction d'assistance groupBy ().


En fin de compte, c'est un autre outil pour votre boîte à outils. Un outil qui, s'il est utilisé correctement, peut conférer des super pouvoirs.


À propos de l'auteur


Chris Ferdinandi aide les gens à apprendre le JavaScript vanille. Il pense qu'il existe un moyen plus simple et plus fiable de faire les choses pour Internet.


Chris est l'auteur de la série Vanilla JS Pocket Guide , créateur du programme d'études Vanilla JS Academy et présentateur du podcast Vanilla JS . Son bulletin d'information destiné aux développeurs est lu par des milliers de développeurs chaque jour de la semaine.


Il a formé des développeurs dans des organisations comme Chobani et le Boston Globe, et ses plugins JavaScript ont été utilisés par Apple et Harvard Business School. Chris Coyer, fondateur de CSS-Tricks et CodePen, a décrit son travail comme "cité à l'infini".


Chris aime les pirates, les chiots et les films Pixar, et vit également près des fermes équestres dans la campagne du Massachusetts. Il dirige Go Make Things avec un chiot Bailey.

Source: https://habr.com/ru/post/fr483182/


All Articles