JavaScript : Décompte des valeurs dans un array

Je vous explique comment compter le nombre d’occurrences des valeurs composants un tableau de données.

3 min de lecture.

Introduction

Bonjour,

Dans ce post, nous allons analyser une fonction qui compte le nombre d’occurrences d’un tableau de données.

Nous verrons les différentes notions de Javascript la composant dont celle que je considère comme la plus importante de ce billet : Array.prototype.reduce().

Fonction fléchée + Array.prototype.reduce() + Objet + Opérateur de coalescence des nuls

Tout d’abord, voici la fonction :

📝 blog.maximebourdon.fr | JavaScript
Réduire la fenêtre
Copier

const calculOccurences = array =>
  array.reduce((objOccurences, v) => {
    objOccurences[v] = (objOccurences[v] ?? 0) + 1;
    return objOccurences;
  }, {});



calculOccurences(['1', '9', '8', '8']); 
// { 1: 1, 9: 1, 8: 2 }

calculOccurences([...'aha']); 
// { a: 2, h: 1 }

Ça peut être un peu complexe à lire si on n’a pas l’habitude et moi-même la première fois que je suis tombé sur cette fonction, je me suis contenté de l’utiliser sans chercher à la comprendre. (Évitez de faire ça. 😈)

Surtout ne vous inquiétez pas nous allons maintenant détailler son fonctionnement.

Fonction fléchée

const calculOccurences = array =>

Tout d’abord on déclare une fonction fléchée nommée calculOccurences qui prend comme paramètre un tableau (ici nommé arbitrairement array, mais qui aurait tout aussi bien pu se nommer data, ou xylophone).

Array.prototype.reduce()

array.reduce((objOccurences, v) => { // FONCTION DE RAPPEL // }, {});

Là ça devient tout de suite plus compliqué si l’on ne connait pas la méthode Array.prototype.reduce().

Elle fait partie avec Array.prototype.filter() et Array.prototype.map() des trois méthodes que vous devez connaitre en JavaScript pour manipuler les tableaux.

filter() (qui permet comme son nom l’indique de filtrer un tableau) et map() (qui vous permet de lire le tableau ligne par ligne) sont simples à appréhender, mais c’est moins le cas pour reduce().

Tout d’abord sachez que reduce() fonctionne comme map() dans le sens ou la méthode lira votre tableau ligne par ligne, mais ajoutera un accumulateur.

Array.prototype.reduce() prend ici deux paramètres :

  • Une fonction de rappel et elle-même prend deux paramètres :
    • objOccurences c’est le résultat obtenu après chaque application de la callback, aussi appelé accumulateur.

      ?

      Callback étant le nom anglais pour Fonction de rappel.
      On ne précisera pas ce que sont exactement ces fonctions dans ce billet, mais je m’y pencherai bientôt, ayant de toute manière envie de coucher ce concept sur papier pour mieux me l’aproprier.

    • v pour valeur, c’est la valeur du tableau en cour de traitement.
  • Une valeur initiale avec , {}); qui est un objet.
    C’est nécessaire de définir cet objet en valeur initiale afin de l’incrémenter au fil du processus pour obtenir à la fin un jeu de clés/valeurs.

    ?

    Sans l’initialisation de cet objet en valeur initiale, reduce nous aurait alors renvoyé un tableau dans objOccurences. Ce qui aurait rendu la callback inopérante.

La fonction de rappel (callback)

Revoyons ensemble la fonction :

📝 blog.maximebourdon.fr | JavaScript
Copier

(objOccurences, v) => {
    objOccurences[v] = (objOccurences[v] ?? 0) + 1;
    return objOccurences;

objOccurences[v] = (objOccurences[v] ?? 0) + 1; cette ligne est le seul et unique traitement de votre fonction de rappel.

C’est elle qui sera appliquée à chaque tour de reduce().

Comprendre son fonctionnement implique de connaitre l’opérateur de coalescence des nuls (nullish coalescing operator).

C’est en fait les ?? et si vous ne savez pas ce que c’est, cela tombe bien car j’ai déjà écrit sur lui. 🤭

Donc cet opérateur vérifiera si la valeur en cours de traitement existe déjà dans objOccurences en tant que clé et si ce n’est pas le cas en initialisera une à 0.

C’est ici que l’objet en valeur initiale prend tout son sens.

En effet, comme vous pouvez le constater on utilise la valeur en cours de traitement comme clé de objOccurences afin de l’incrémenter de un.

Finalement, on retourne objOccurences pour la prochaine callback ou pour terminer la reduce.

Croquis

Pour vous aider à mieux appréhender tout cela, voici un petit croquis que j’ai concocté rien que pour vous. 🙃

Diagramme représentant le fonctionnement de la fonction.

Conclusion

Avec cette idée qui semblait simple au départ, nous avons pu voir quelques concepts du JavaScript et notamment Array.prototype.reduce() .

N’hésitez pas, abusez en quand vous aurez à manipuler des tableaux !

Ca sera toujours mieux qu’une boucle for in. 🧐

A bientôt !

Article inspiré par :
https://www.30secondsofcode.org/js/s/value-frequencies/

Fil d'Ariane 💃