Reduce es una función que a menudo nos resulta intimidante al principio, pero en realidad su esencia es bastante sencilla y poderosa. En JavaScript, Reduce nos permite transformar un array en un único valor, que puede ser un número, un objeto, otro array o cualquier tipo de dato. Esto lo diferencia de funciones como map, que transforman un array en otro array con el mismo número de elementos, aplicando una operación a cada uno de ellos.
Para entender mejor cómo funciona Reduce, pensemos en un array de letras, por ejemplo ['A', 'B', 'C', 'D']. Mientras que map nos devolvería otro array con la misma cantidad de elementos transformados, Reduce nos permite condensar todo ese array en un solo valor. Por ejemplo, podríamos sumar el total de caracteres de todas las palabras en un array, o agrupar tareas según su prioridad en un objeto.
Un caso común de uso es sumar los precios de un carrito de compras representado como un array de números. Reduce nos permite iterar sobre cada elemento y acumular la suma total, devolviendo un único número que representa el total. Otro ejemplo más complejo es agrupar tareas por prioridad en un objeto, donde cada clave representa una prioridad y su valor es un array con las tareas correspondientes.
El funcionamiento de Reduce se basa en dos parámetros principales: un callback y un valor inicial para el acumulador. El callback es una función que se ejecuta una vez por cada elemento del array, recibiendo como parámetros el acumulador y el elemento actual. El acumulador es una variable que se va actualizando en cada iteración con el resultado parcial, y que finalmente se devuelve como resultado total de la operación.
Veamos un ejemplo sencillo para contar el total de letras en un array de palabras:
const flores = ['Margarita', 'Amapola', 'Petunia', 'Geranio'];
const totalLetras = flores.reduce((acumulador, item) => {
console.log('Acumulador:', acumulador, 'Item:', item);
return acumulador + item.length;
}, 0);
console.log('Total de letras:', totalLetras);
En este código, el acumulador comienza en 0. En cada iteración, sumamos la longitud de la palabra actual al acumulador. Así, después de procesar todas las palabras, obtenemos el total de letras. Durante la ejecución, podemos observar cómo el acumulador va aumentando con cada palabra.
Otro ejemplo más avanzado es agrupar tareas por prioridad. Supongamos que tenemos un array de objetos donde cada objeto representa una tarea con una propiedad prioridad que puede ser 'A', 'B' o 'C'. Queremos transformar este array en un objeto que tenga como claves las prioridades y como valores arrays con las tareas correspondientes.
Podemos hacerlo así:
const tareas = [
{ nombre: 'Tarea 1', prioridad: 'A' },
{ nombre: 'Tarea 2', prioridad: 'B' },
{ nombre: 'Tarea 3', prioridad: 'A' },
{ nombre: 'Tarea 4', prioridad: 'C' },
{ nombre: 'Tarea 5', prioridad: 'B' }
];
const tareasPorPrioridad = tareas.reduce((objeto, tarea) => {
if (!objeto[tarea.prioridad]) {
objeto[tarea.prioridad] = [];
}
objeto[tarea.prioridad].push(tarea);
return objeto;
}, {});
console.log(tareasPorPrioridad);
Aquí, el acumulador es un objeto vacío que vamos llenando con arrays para cada prioridad. En cada iteración, comprobamos si la prioridad de la tarea ya existe como clave en el objeto; si no, la inicializamos con un array vacío. Luego, añadimos la tarea al array correspondiente. Al final, obtenemos un objeto que agrupa las tareas según su prioridad.
Es importante tener en cuenta que aunque Reduce es muy flexible y potente, no siempre es la mejor opción para todas las situaciones. A veces, usar funciones específicas como sum o métodos más claros puede hacer que nuestro código sea más legible y fácil de mantener. Reduce puede llevar a escribir código complicado si no se usa con cuidado.
En resumen, Reduce nos permite acumular resultados parciales a lo largo de un array para obtener un único valor final. Su callback recibe el acumulador y el elemento actual, y debe devolver el nuevo valor del acumulador para la siguiente iteración. El valor inicial del acumulador es fundamental para definir el tipo de resultado que queremos construir, ya sea un número, un objeto o cualquier otro tipo.
Con estos conceptos claros y algunos ejemplos prácticos, podemos empezar a integrar Reduce en nuestros desarrollos con confianza y aprovechar su potencial para transformar arrays en valores únicos de forma eficiente y elegante.