Le currying en javascript, application pratique

par | Août 23, 2021 | javascript | 0 commentaires

Dans un précédent post, j’ai abordé le principe de base du currying en javascript, en montrant comment on peut faire un usage partiel d’une combinaison de fonctions.

Aujourd’hui je vous propose de réaliser une fonction permettant de filtrer une collection basée sur ce principe.

Nous allons avoir besoin d’un fichier javascript et d’un environnement node.js pour exécuter le code.

Tout d’abord nous allons créer un document javascript et créer une collection d’objets, soit un tableau d’objets que nous allons placer dans une constante :

const collection = [
 {
    nom: 'test 1',
    rarete: 'rare',
    couleur: 'rouge',
  },
  {
    nom: 'test 2',
    rarete: 'rare',
    couleur: 'noir',
  },
  {
    nom: 'test 3',
    rarete: 'commune',
    couleur: 'vert',
  },
];

Oui en tant que vieux joueur the MTG je n’ai pas pu résister 🙂

Nous allons ensuite créer une fonction qui va prendre la collection, puis la filtrer en se basant sur un critère et donner une valeur pour ce critère.

La fonction doit être de la forme : carte de la collection => critère === valeur

Pour cela nous utilisons la fonction .filter() et écrire la fonction suivante :

const filtre = (tableau) => (clef) => (valeur) =>
  tableau.filter((carte) => carte[clef] === valeur);

On retrouve bien le principe de fonctionnement indiqué.

Usage

Usage de la fonction complète

Nous pouvons utiliser la fonction en précisant à chaque fois tous les paramètres.

Par exemple :

console.log('filtre: ', filtre(collection)('rarete')('rare'));

// affichera :
// filtre:  [
//  { nom: 'test 1', rarete: 'rare', couleur: 'rouge' },
//  { nom: 'test 2', rarete: 'rare', couleur: 'noir' }
// ]

Ou encore :

console.log('filtre: ', filtre(collection)('couleur')('rouge'));

// affichera 
// filtre:  [ { nom: 'test 1', rarete: 'rare', couleur: 'rouge' } ]

Mais nous pouvons également créer des filtres prédéfinis :

Usage en composant de nouvelles fonctions

Si je veux créer un filtre par couleur, je défini ce filtre en réalisant une composition partielle :

const filtreCouleur = filtre(collection)('couleur');

Il ne me reste plus qu’à l’utiliser en précisant la valeur de la couleur souhaitée

console.log('filtreCouleur: ', filtreCouleur('vert'));

// affichera
// filtreCouleur:  [ { nom: 'test 3', rarete: 'commune', couleur: 'vert' } ]

Et un filtre rareté sur le même principe :

const filtreRarete = filtre(collection)('rarete');

console.log('filtreRarete: ', filtreRarete('rare'));

// affichera
// filtreRarete:  [
//   { nom: 'test 1', rarete: 'rare', couleur: 'rouge' },
//   { nom: 'test 2', rarete: 'rare', couleur: 'noir' }
// ]

Pour aller un peu plus loin

Si nous souhaitons maintenant filtrer par rareté et par couleur, il faut passer en paramètre de la fonction le résultat du filtre de rareté, et filtrer par couleur :

const filtreCouleur = filtre(collection)('couleur');
const filtreRarete = filtre(collection)('rarete');

console.log(
  'filtreRareteEtCouleur: ',
  filtre(filtreRarete('rare'))('couleur')('noir')
);

// affichera
// filtreCouleurEtRarete:  [ { nom: 'test 2', rarete: 'rare', couleur: 'noir' } ]

Conclusion

Le currying offre des possibilités puissantes avec l’utilisation partielle des fonctions.

J’utilise ces principes dès que possibles pour simplifier l’écriture du code et de prioriser la factorisation et la réutilisation au maximum.

Le code complet utilisé pour notre exemple :

const collection = [
  {
    nom: 'test 1',
    rarete: 'rare',
    couleur: 'rouge',
  },
  {
    nom: 'test 2',
    rarete: 'rare',
    couleur: 'noir',
  },
  {
    nom: 'test 3',
    rarete: 'commune',
    couleur: 'vert',
  },
];

const filtre = (tableau) => (clef) => (valeur) =>
  tableau.filter((carte) => carte[clef] === valeur);

const filtreCouleur = filtre(collection)('couleur');
const filtreRarete = filtre(collection)('rarete');


console.log('filtre: ', filtre(collection)('rarete')('rare'));
console.log('filtre: ', filtre(collection)('couleur')('rouge'));
console.log('filtreCouleur: ', filtreCouleur('vert'));
console.log('filtreRarete: ', filtreRarete('rare'));

console.log(
  'filtreCouleurEtRarete: ',
  filtre(filtreRarete('rare'))('couleur')('noir')
);

Happy coding !

0 commentaires

Soumettre un commentaire

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

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.