DEV Community

Cover image for Las bondades del método reduce() en JavaScript.
Cristian Fernando
Cristian Fernando

Posted on

Las bondades del método reduce() en JavaScript.

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)
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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}
];
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
let numeros =[8,3,7,9,4,0];
const min = numeros.reduce((acc,numero) => Math.min(acc,numero))

console.log(min); //salida: 0
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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 e item.
  • Es un método inmutable.

Referencias

link

Top comments (2)

Collapse
 
duxtech profile image
Cristian Fernando

Muchas gracias por leer mi post! te agradezco la recomendación, un saludo cordial!
PD: Lo siento por responder tu comentario tan tarde XD

Collapse
 
canarioechazu profile image
Dario Canario Echazu

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