reduce()
es un método bastante peculiar, ampliamente usado pero al mismo tiempo incomprendido por las comunidades de desarrollo. Junto con map()
y filter()
completan lo que me gusta denominar como la Trinidad de los métodos JavaScript.
En este pequeño post trataré de resumir y explicar las principales características del método reduce()
con ejemplos prácticos.
Al igual que map()
y filter()
, reduce()
itera sobre un arreglo dado.
Sintaxis
array.reduce( (acc, item, index, arr)=>{
//cuerpo de la funcion
}, inicilizador del acumulador)
reduce()
recibe un callback con 4 parámetros:
- acc: variable acumuladora donde se almacenarán valores parciales en cada iteración del arreglo.
- item: elemento actual del arreglo que se itera.
- index: posición del elemento anterior mencionando.
- arr: arreglo como tal, sobre el cual se trabaja.
En la práctica, casi para cualquier caso se uso se acostumbra solo usar la variable acc
e item
, por lo que una sintaxis más resumida se vería de la siguiente manera:
array.reduce( (acc, item)=>{
//cuerpo de la funcion
}, inicilizador del acumulador)
El inicializador del acumulador se explicará a detalle con los ejemplos practicos.
Características de reduce()
-
reduce()
reduce (valga la redundancia) el arreglo a un solo valor, en otras palabras, devolverá un solo valor. - Ejecuta un callback para cada elemento del arreglo.
- El valor de retorno de la función se almacena en una variable acumuladora (
acc
). - No se ejecuta en arreglos vacíos.
- Es inmutable, no altera ni modifica el arreglo original.
Basta de conceptos teóricos, ahora analicemos ejemplos prácticos:
Imaginemos que tenemos un array de números y deseamos sumar todos sus valores, podríamos usar reduce()
de la siguiente manera:
let numeros =[2,9,7,16,3,78];
let suma = numeros.reduce((acc,numero) => acc + numero);
console.log(suma);
//salida: 115
Expliquemos a detalle que sucedió acá:
Al no usar un valor de inicialización, acc = 2
, por ser el primer elemento de nuestro arreglo.
La iteración del arreglo, por ende, comenzará desde el index 1, osea, el número 9: numero = 9
La siguiente tabla explica el flujo del programa:
Iteración | acc | numero | acc + numero |
---|---|---|---|
1ra iteración | 2 | 9 | 11 |
2da iteración | 11 | 7 | 18 |
3ra iteración | 18 | 16 | 34 |
4ta iteración | 34 | 3 | 37 |
5ta iteración | 37 | 78 | 115 |
Analizando iteración a iteración se comprende mucho mejor de donde sale el resultado final.
Veamos otro ejemplo:
Imaginemos que tenemos un arreglo de objetos que contienen pedidos de comida, entonces el chef nos pide que le indiquemos cuantos son los pedidos cuyo plato principal sea "sajta", ¿cómo podríamos hacer esto con reduce()
? El arreglo de objetos es el siguiente:
let pedidos = [
{entrada:'ensalada de pepinos', principal: 'sajta', postre: "platano"},
{entrada:'ensalada de tomates', principal: 'silpancho', postre: "helado"},
{entrada:'ensalada simple', principal: 'sajta', postre: "yogurt"},
{entrada:'ensalada simple', principal: 'anticucho', postre: "yogurt"},
{entrada:'ensalada de tomates', principal: 'sajta', postre: null}
];
La sajta es un plato típico boliviano elaborado en base a pollo, ají, papas, y salsa
Una posible solución es la siguiente:
let cantidadSajta = pedidos.reduce((contador,pedido)=>{
if(pedido.principal === "sajta")
return contador+1;
else
return contador;
},0)
console.log(cantidadSajta); //salida: 3
Podemos observar que en este ejemplo si escribimos una inicialización para la variable contador que es 0, (contador = 0
). Esto hace que el iterador recorra el arreglo desde el índice 0 y no desde el índice 1 como vimos en el anterior ejemplo.
Encontrar el mínimo o máximo
Los métodos min()
y max()
de Math usadas con reduce()
facilitan encontrar el mínimo y máximo en un arreglo de números:
let numeros =[8,3,7,9,4,0];
const max = numeros.reduce((acc,numero) => Math.max(acc,numero))
console.log(max); //salida: 9
let numeros =[8,3,7,9,4,0];
const min = numeros.reduce((acc,numero) => Math.min(acc,numero))
console.log(min); //salida: 0
Trabajar con arreglos anidados
Imaginemos que contamos con un arreglo anidado y necesitamos convertirlo en un arreglo plano.
let numeros =[1,2,[3,4,5],6,7,[8],[9,10]];
const planos = numeros.reduce((acc,item) =>{
return acc.concat(item)
},[]);
console.log(planos);
//salida: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Conclusiones
-
reduce()
itera y compara cada elemento de un arreglo, aplicando un callback y devolviendo un solo valor. - El callback recibe 4 parámetros pero en la práctica solo usamos 2:
acc
eitem
. - Es un método inmutable.
Top comments (2)
Muchas gracias por leer mi post! te agradezco la recomendación, un saludo cordial!
PD: Lo siento por responder tu comentario tan tarde XD
Tengo una duda.
Veo que aquí llaman al array pedidos al aplicar reduce, en la funcion flecha en parametros está sin "s" como pedido.
Entonces qué es lo que está efectuando reduce, otro array?
Gracias.
Abajo dejé el código que tengo dudas.
let cantidadSajta = pedidos.reduce((contador,pedido)=>{
if(pedido.principal === "sajta")
return contador+1;
else
return contador;
},0)
console.log(cantidadSajta); //salida: 3