Le terme "réduire" est en fait un terme fonctionnel utilisé en programmation fonctionnelle. Dans un langage comme Haskell, F# ou même JavaScript, nous définissons une transformation qui prend une collection (de n'importe quelle taille) en entrée et renvoie une seule valeur en sortie.
Donc (sans vouloir être pédant, mais je trouve que cela m'aide) pensez-y visuellement. Nous avons une collection :
[][][][][][][][][][]
...que nous voulons réduire à une seule valeur :
N
En programmant de manière fonctionnelle, nous ferions cela avec une seule fonction que nous pourrions appeler de manière récursive sur chaque élément de la collection. Mais si vous faites cela, vous devez garder la trace de la valeur intermédiaire quelque part, n'est-ce pas ? Les implémentations non pures pourraient conserver une sorte d'"accumulateur" ou de variable en dehors de la fonction pour garder la trace de l'état, comme ceci :
var accumulator = 0;
var myArray = [1,2,3,4,5];
myArray.reduce(function (each) {
accumulator += 0;
});
return accumulator;
Avec les fonctions pures, cependant, nous ne pouvons pas le faire - car par définition, les fonctions pures ne peuvent pas avoir d'effets en dehors de leur portée. Au lieu de s'appuyer sur une variable externe qui encapsule notre "état" entre les appels, nous transmettons simplement l'état dans la méthode :
var myArray = [1,2,3,4,5];
return myArray.reduce(function (accumulator, each) {
return accumulator + each;
}, 0);
Dans ce cas, nous appelons la fonction un "réducteur" en raison de la signature de sa méthode. Nous avons each
(ou current
- n'importe quel nom convient), représentant un objet de la collection ; et state
(ou previous
), qui est transmis à chaque itération de la fonction, représentant les résultats de la transformation que nous avons déjà effectuée sur les éléments précédents de la collection.
Notez que la documentation MDN que vous avez référencée est correcte ; la fonction reduce()
renvoie toujours une seule valeur. En fait, la fonction reduce
dans n'importe quel langage est une fonction d'ordre supérieur qui prend un "réducteur" (une fonction avec la signature de méthode définie ci-dessus) et renvoie une seule valeur. Maintenant, oui, vous peut faire d'autres choses avec, si la fonction que vous appelez a des effets secondaires, mais vous ne devriez pas. (Essentiellement, n'utilisez pas .reduce()
comme un foreach). Même si la méthode que vous appelez avec reduce
a des effets secondaires, le valeur de retour de réduire lui-même sera une valeur unique, et non une collection.
Ce qui est génial, c'est que ce modèle ne s'applique pas uniquement aux tableaux ou aux collections concrètes, comme vous l'avez vu dans React ; ce modèle peut également être appliqué aux flux, puisqu'il s'agit de fonctions pures.
J'espère que cela vous aidera. Pour ce que ça vaut, la définition sur le site de Redux pourrait être améliorée (car le concept de réducteur n'est pas seulement dû à la méthode Array prototype de Javascript). Vous devriez soumettre un PR !
Edit : Il y a un article Wikipedia sur le sujet. Notez que la réduction a différents noms, et dans les langages fonctionnels, elle est communément appelée Fold. https://en.wikipedia.org/wiki/Fold_(fonction d'ordre supérieur)#Plis_comme_transformations_structurelles
Modifier (2020-10-03) : Les gens semblent toujours trouver cela utile - c'est bien. Avec le temps, je me suis rendu compte que "fold" est un bien meilleur terme pour cela ; les langages fonctionnels l'ont bien compris. "Réducteur" n'est pas vraiment un mauvais terme, mais ce n'est pas nécessairement un bon terme non plus.
9 votes
Excellente question !
0 votes
Pour moi, qui viens de WPF et de C#, les actions semblent être l'action "setter" et les réducteurs sont l'action "getter". Bien qu'il ne fonctionne pas réellement de cette façon sous le capot, car il renvoie un objet d'état complètement nouveau au lieu de le modifier, mais le résultat final est similaire à ce qu'il accomplit.
0 votes
En tant que développeur avec plus de 15 ans d'expérience en Java, .NET, Android, Angular, PHP, et d'autres piles, je peux dire avec certitude que les dénominations dans redux sont tout simplement une honte pour la communauté de développement. Les développeurs de redux devraient avoir honte de confondre des générations de développeurs.