La méthode reduce()
applique une fonction qui est un « accumulateur » et qui traite chaque valeur d'une liste (de la gauche vers la droite) afin de la réduire à une seule valeur.
var somme = [0, 1, 2, 3].reduce(function(a, b) { return a + b; }, 0); // somme vaut 6
Syntaxe
arr.reduce(callback) arr.reduce(callback, valeurInitiale)
Paramètres
callback
- La fonction à exécuter sur chaque valeur de la liste, elle prend quatre arguments en entrée :
valeurPrecedente
- La valeur précédemment retournée par le dernier appel du callback, ou
valeurInitiale
, si elle est fournie (voir ci-après). valeurCourante
- La valeur de l'élément courant actuellement manipulé dans le tableau.
index
- L'index de l'élément courant actuellement manipulé dans le tableau.
array
- Le tableau sur lequel on a appelé la méthode
reduce
.
valeurInitiale
Facultatif- Une valeur utilisée comme premier argument lors du premier appel de la fonction
callback
.
Valeur de retour
La valeur obtenue grâce à la fonction de réduction.
Description
reduce
exécute la fonction callback
une fois pour chaque élément présent dans le tableau et ignore les éléments vides du tableau. La fonction callback
utilise quatre arguments :
- la valeur initiale (ou la valeur retournée par le précédent appel de la fonction
callback
) ; - la valeur de l'élément courant ;
- l'index de l'élément courant ;
- le tableau parcouru par la méthode.
La première fois que la fonction callback
est appelée, valeurInitiale
et valeurCourante
peuvent correspondre à un ou deux éléments. Si valeurInitiale
est fournie dans l'appel de reduce
, alors valeurPrecedente
sera égale à valeurInitiale
et valeurCourante
sera égale à la première valeur de la liste. Si valeurInitiale
n'est pas fournie, alors valeurPrécédente
sera égale à la première valeur de la liste, et valeurCourante
sera alors égale à la seconde.
En considérant le code suivant :
[0, 1, 2, 3, 4].reduce(function(valeurPrecedente, valeurCourante, index, array){ return valeurPrecedente + valeurCourante; });
La fonction callback
sera appelée quatre fois, avec les arguments et les valeurs de retour de chaque appel suivant :
valeurPrecedente |
valeurCourante |
index |
array |
valeur retournée | |
---|---|---|---|---|---|
premier appel | 0 |
1 |
0 |
[0,1,2,3,4] |
1 |
deuxième appel | 1 |
2 |
1 |
[0,1,2,3,4] |
3 |
troisième appel | 3 |
3 |
2 |
[0,1,2,3,4] |
6 |
quatrième appel | 6 |
4 |
3 |
[0,1,2,3,4] |
10 |
La valeur retournée par reduce
sera alors celle du dernier appel de la callback (ici 10
).
Il est aussi possible d'utiliser une fonction fléchée au lieu d'une fonction classique. Le code suivant, par exemple, produit le même résultat que l'exemple précédent :
[0, 1, 2, 3, 4].reduce( (valeurPrécédente, valeurCourante) => valeurPrécédente + valeurCourante);
Si on fournit une valeur initiale comme second argument à l'appel de reduce
, le résultat sera alors le suivant :
[0, 1, 2, 3, 4].reduce(function(valeurPrecedente, valeurCourante, index, array){ return valeurPrecedente + valeurCourante; }, 10);
valeurPrecedente |
valeurCourante |
index |
array |
valeur retournée | |
---|---|---|---|---|---|
premier appel | 10 |
0 |
0 |
[0,1,2,3,4] |
10 |
deuxième appel | 10 |
1 |
1 |
[0,1,2,3,4] |
11 |
troisième appel | 11 |
2 |
2 |
[0,1,2,3,4] |
13 |
quatrième appel | 13 |
3 |
3 |
[0,1,2,3,4] |
16 |
cinquième appel | 16 |
4 |
4 |
[0,1,2,3,4] |
20 |
Ici, la valeur renvoyée par reduce
serait 20
.
Exemples
Additionner toutes les valeurs d'un tableau
var total = [0, 1, 2, 3].reduce((a, b)=> a + b,0); // total == 6
Aplatir une liste de listes
var aplati = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) { return a.concat(b); }); // aplati vaut [0, 1, 2, 3, 4, 5]
Utiliser le paramètre valeurInitiale
var amis = [ { "nom": "Quentin", "livres": ["City Hall", "Harry Potter"]}, { "nom": "Alice", "livres": ["L'Avare", "Les Fleurs du Mal"]} ] var tousLivres = amis.reduce(function(prev, curr) { return [...prev, ...curr.livres]; }, ["Perceval"]); // tousLivres = ["Perceval", "City Hall", "Harry Potter", // "L'Avare", "Les Fleurs du Mal"]
Prothèse d'émulation (polyfill)
Array.prototype.reduce
a été ajoutée à la 5ème édition du standard ECMA-262 (ECMAScript 5), il se peut donc qu'elle ne soit pas présente dans toutes les implémentations du standard. Vous pouvez contourner ce problème en ajoutant le code suivant au début de vos scripts qui vous permettra d'utiliser la méthode reduce
dans des environnements qui n'en disposent pas nativement.
// Production steps, ECMA-262, Edition 5, 15.4.4.21 // Référence : https://es5.github.io/#x15.4.4.21 if (!Array.prototype.reduce) { Array.prototype.reduce = function(callback /*, initialValue*/) { 'use strict'; if (this === null) { throw new TypeError('Array.prototype.reduce appelé sur null ou undefined'); } if (typeof callback !== 'function') { throw new TypeError(callback + ' n est pas une fonction'); } var t = Object(this), len = t.length >>> 0, k = 0, value; if (arguments.length == 2) { value = arguments[1]; } else { while (k < len && ! (k in t)) { k++; } if (k >= len) { throw new TypeError('Réduction de tableau vide sans valeur initiale'); } value = t[k++]; } for (; k < len; k++) { if (k in t) { value = callback(value, t[k], k, t); } } return value; }; }
Spécifications
Spécification | État | Commentaires |
---|---|---|
ECMAScript 5.1 (ECMA-262) La définition de 'Array.prototype.reduce' dans cette spécification. |
Standard | Définition initiale. Implémenté dans JavaScript 1.8 |
ECMAScript 2015 (6th Edition, ECMA-262) La définition de 'Array.prototype.reduce' dans cette spécification. |
Standard | |
ECMAScript 2017 Draft (ECMA-262) La définition de 'Array.prototype.reduce' dans cette spécification. |
Projet |
Compatibilité des navigateurs
Fonctionnalité | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Support simple | (Oui) | 3.0 (1.9) | 9 | 10.5 | 4.0 |
Fonctionnalité | Android | Chrome pour Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Support simple | (Oui) | (Oui) | (Oui) | (Oui) | (Oui) | (Oui) |