• Contenu
  • Bas de page
logo ouidoulogo ouidoulogo ouidoulogo ouidou
  • Qui sommes-nous ?
  • Offres
    • 💻 Applications métier
    • 🤝 Collaboration des équipes
    • 🛡️ Sécurisation et optimisation du système d’information
    • 🔗 Transformation numérique
  • Expertises
    • 🖥️ Développement logiciel
    • ♾️ DevSecOps
    • ⚙️ Intégration de logiciels et négoce de licences
      • Atlassian : Jira, Confluence, Bitbucket…
      • Plateforme monday.com
      • GitLab
      • SonarQube
    • 📚​ Logiciel de CRM et de gestion
    • 🎨 UX/UI design
    • 🌐 Accessibilité Numérique
    • 🗂️​ Démarches simplifiées
    • 📝 Formations Atlassian
  • Références
  • Carrières
    • 🧐 Pourquoi rejoindre Ouidou ?
    • ✍🏻 Nous rejoindre
    • 👨‍💻 Rencontrer nos collaborateurs
    • 🚀 Grandir chez Ouidou
  • RSE
  • Ressources
    • 🗞️ Actualités
    • 🔍 Articles techniques
    • 📖 Livres blancs
    • 🎙️ Interviews Clients
Nous contacter
✕
Vue.js London 2018, en résumé.
Vue.js London 2018, en résumé.
4 octobre 2018
Droits et rôles dans une architecture orientée domaine
Droits et rôles dans une architecture orientée domaine
8 novembre 2018
Ressources > Articles techniques > Chérie, j’ai reduce les tableaux

Chérie, j’ai reduce les tableaux

Article écrit par Tom Panier

Depuis un peu plus d’un an que j’écris sur ce blog, je vous ai surtout parlé de Vue.js, ou encore d’outils comme ESLint ; mais tous les bons artisans vous le diront, avoir le meilleur marteau du monde n’interdit pas de s’écraser les doigts !

Aujourd’hui, laissons donc de côté le strass et les paillettes et mettons les deux mains dans le cambouis : en tant que développeur·se JavaScript, à quel point maîtrisez-vous votre langage préféré ? Savez-vous vraiment utiliser Array.prototype.reduce ?

J'ai reduce les tableaux

Ça fait peur…

…et c’est bien dommage, car utiliser cette fonction est diablement simple une fois qu’on a compris comment elle marche !

En deux mots, reduce a pour objectif de transformer un tableau en n’importe quoi d’autre, en itérant progressivement sur ce tableau et en apportant des modifications successives à un accumulateur, ce dernier constituant au final la valeur de retour ! C’est plus clair ?

…Non ? Bon, prenons un exemple tout bête :

const values = [1, 2, 3, 4]; 

Quelle est selon vous la manière la plus simple de calculer la somme d’un tableau de Number ?

let sum = 0;  values.forEach(value => {   sum += value; }); 

Ça fonctionne, mais il y a plus simple, vous vous en doutez, avec reduce :

const sum = values.reduce((acc, cur) => acc + cur, 0); 

Décomposons cette petite ligne de code :

  • reduce prend en premier paramètre une fonction, appelée sur chacun des éléments de values
  • celle-ci prend deux paramètres : un accumulateur (typiquement noté acc) et une valeur courante (typiquement notée cur), à savoir l’élément courant dans values
  • la valeur retournée par la fonction sera la valeur d’acc au tour de boucle suivant
  • enfin, le second paramètre de reduce donne la valeur de départ d’acc (qui en a besoin au premier tour de boucle puisque notre fonction n’a pas encore été exécutée)

Vous l’aurez donc compris, au premier tour de boucle, la fonction renverra 1 (0 + 1), au second 3 (1 + 2), au troisième 6 (3 + 3) et au quatrième 10 (6 + 4), ce qui sera également la valeur de sum en fin d’exécution !

La notion d’accumulateur doit désormais vous paraître plus claire, et le fonctionnement de reduce lui-même également, de fait ! Afin de vous familiariser avec, voyons ensemble des cas d’utilisation plus complexes, qui vous démontreront toute sa puissance.

D’objet à tableau

On peut parfois avoir besoin de transformer un objet en tableau :

const obj = {   foo: { value: "bar" },   bar: { value: "baz" } }; 

Pour ce faire, nous allons utiliser Object.keys afin de pouvoir itérer sur le tableau contenant les clés de notre objet :

Object.keys(obj).reduce((acc, key) => [...acc, { key, value: obj[key].value }], []); 

La décomposition (...) utilisée sur acc revient au même qu’appeler concat dessus.

Notre objet initial devient donc le tableau suivant :

[   { key: "foo", value: "bar" },   { key: "bar", value: "baz" } ] 

Valider un tableau (ou un objet)

La fonction peut également servir à obtenir un booléen après avoir parcouru l’intégralité d’un tableau (ou d’un objet), en validant tel ou tel aspect de chaque élément :

const allInputsAreFilled = Array.from(document.querySelectorAll("input")).reduce((acc, cur) => acc && !!cur.value, true); 

Effectuer des remplacements dynamiques dans une chaîne

reduce peut aussi être utile dans un tel cas :

const obj = {   foo: "Jean-Pierre",   bar: "Thierry",   baz: "Gaston" };  const subject = "{foo} dit alors à {bar} que c'était la faute de {baz}."; 

Comme dans l’exemple précédent, tirons parti d’Object.keys :

Object.keys(obj).reduce((acc, cur) => acc.replace(new RegExp(`{${cur}}`), obj[cur]), subject); 

Et voici le résultat :

"Jean-Pierre dit alors à Thierry que c'était la faute de Gaston." 

Bien évidemment, ce pattern s’avère en pratique plus pertinent sur de la gestion d’URLs, par exemple.

Agréger les objets d’un tableau

Imaginons ensuite un tableau d’objets, que l’on souhaite agréger en fonction d’une de leurs clés :

const tasks = [   { id: 1, label: "foo", state: "open" },   { id: 2, label: "bar", state: "close" },   { id: 3, label: "baz", state: "open" },   { id: 4, label: "qux", state: "open" },   { id: 5, label: "kek", state: "close" } ]; 
tasks.reduce((acc, cur) => {   if (!(cur.state in acc)) {     acc[cur.state] = [];   }    acc[cur.state].push(cur);    return acc; }, {}); 

Ce qui nous donne :

{   open: [     { id: 1, label: "foo", state: "open" },     { id: 3, label: "baz", state: "open" },     { id: 4, label: "qux", state: "open" }   ],   close: [     { id: 2, label: "bar", state: "close" },     { id: 5, label: "kek", state: "close" }   ] } 

En tirant parti de la décomposition, notre reduce peut par ailleurs être écrit de manière plus concise :

tasks.reduce((acc, cur) => ({   ...acc,   ...{ [cur.state]: [...acc[cur.state] || [], cur] } }), {}); 

Appliquer récursivement un traitement sur un objet complexe

Prenons enfin l’objet suivant, en partant du principe que nous voulons remplacer toutes les occurrences de "non" par "oui" :

const obj = {   foo: "non",   bar: {     baz: "non",     uno: 1,     qux: {       kek: "non",       dos: 2,       arr: [3, "non", { foo: "non", bar: "baz" }]     }   } }; 
function processValue(value) {   if (typeof value === "object") { // objet ou tableau     return processValues(value);   }    return value === "non" ? "oui" : value; // le traitement effectif }  function processValues(values) {   return Object.keys(values).reduce((acc, cur) => {     if (Array.isArray(values[cur])) {       return { ...acc, [cur]: values[cur].map(item => processValue(item)) };     }      return { ...acc, [cur]: processValue(values[cur]) };   }, {}); }  processValues(obj); 

Le résultat est à la hauteur de nos espérances :

{   foo: "oui",   bar: {     baz: "oui",     uno: 1,     qux: {       kek: "oui",       dos: 2,       arr: [3, "oui", { foo: "oui", bar: "baz" }]     }   } } 

Gai mauve heure

J’espère de tout cœur que ces quelques exemples vous auront donné une meilleure idée des cas d’usage d’Array.prototype.reduce ! N’oubliez pas que les tableaux en JavaScript ont une armada d’autres méthodes à disposition, lesquelles se combineront fort efficacement avec celle que nous venons de voir (map, filter…).

Si, par le plus grand des hasards, vous utilisez Vue.js (ou un autre framework du même acabit, tel React), reduce sera un allié de poids dans la définition de vos computeds, notamment — et je ne parle même pas de Redux et de ses reducers, des noms qui devraient normalement commencer à vous rappeler quelque chose 😉

Je vais vous laisser bricoler avec tout ça, et vous donner rendez-vous très prochainement pour un nouvel article !

À lire aussi

Fresque numérique miniature image
16 avril 2025

Fresque du Numérique

Lire la suite

intelligence artificielle Ouicommit miniature image
17 mars 2025

Ouicommit – L’intelligence artificielle en entreprise, on y est ! 

Lire la suite

Image miniature Hackathon Women in Tech
13 mars 2025

Hackathon Women in Tech :  un engagement pour une tech plus inclusive 

Lire la suite

image miniature les nouveautés Atlassian
26 février 2025

Les nouveautés Atlassian en 2025

Lire la suite

Articles associés

Fresque numérique miniature image
16 avril 2025

Fresque du Numérique


Lire la suite
intelligence artificielle Ouicommit miniature image
17 mars 2025

Ouicommit – L’intelligence artificielle en entreprise, on y est ! 


Lire la suite
Image miniature Hackathon Women in Tech
13 mars 2025

Hackathon Women in Tech :  un engagement pour une tech plus inclusive 


Lire la suite

À propos

  • Qui sommes-nous ?
  • Références
  • RSE
  • Ressources

Offres

  • Applications métier
  • Collaboration des équipes
  • Sécurisation et optimisation du système d’information
  • Transformation numérique

Expertises

  • Développement logiciel
  • DevSecOps
  • Intégration de logiciels et négoce de licences
  • Logiciel de CRM et de gestion
  • UX/UI design
  • Accessibilité Numérique
  • Démarches simplifiées
  • Formations Atlassian

Carrières

  • Pourquoi rejoindre Ouidou ?
  • Nous rejoindre
  • Rencontrer nos collaborateurs
  • Grandir chez Ouidou

SIEGE SOCIAL
70-74 boulevard Garibaldi, 75015 Paris

Ouidou Nord
165 Avenue de Bretagne, 59000 Lille

Ouidou Rhône-Alpes
4 place Amédée Bonnet, 69002 Lyon

Ouidou Grand-Ouest
2 rue Crucy, 44000 Nantes

Ouidou Grand-Est
7 cour des Cigarières, 67000 Strasbourg

  • Linkedin Ouidou
  • GitHub Ouidou
  • Youtube Ouidou
© 2024 Ouidou | Tous droits réservés | Plan du site | Mentions légales | Déclaration d'accessibilité
    Nous contacter