DEV Community

Cover image for js❤️ - .map, .forEach, .find, .filter, .reduce
Javi Carrasco
Javi Carrasco

Posted on • Updated on

js❤️ - .map, .forEach, .find, .filter, .reduce

.map, .forEach, .find, .filter, .reduce

La mayoría de estos métodos ya estaban antes de es6 pero creo que resulta muy útil hablar de ellos también.

map. Permite ejecutar una transformación a cada uno de los elementos de un array sin modificar la colección original

planets.map(({ name }) => name.toLowecase());
// [ "mercury", "venus", "earth", "mars", "jupiter", "saturn", "uranus", "neptune", "pluto"]
Enter fullscreen mode Exit fullscreen mode

forEach. Permite ejecutar una función sobre cada elemento de la colección. Sin embargo no devuelve un nuevo array con los resultados como hace .map

planets.forEach((planet) =>
  fetch("/savePlanet", { method: "POST", body: JSON.stringify(planet) })
);
Enter fullscreen mode Exit fullscreen mode

find. Permite encontrar el primer elemento que cumple la condición

roles.find(({id}) => id === 'admin')
// {id: "admin", name: "Administrator", ...}
Enter fullscreen mode Exit fullscreen mode

filter. Obtiene el subconjunto de los elementos que cumplen la condición

const productsOutOfStock = products.filter((product) => !product.hasStock);
Enter fullscreen mode Exit fullscreen mode

reduce. Devuelve un solo valor que resume el array. Sirve para hacer agregados como la suma, la media, la mediana, etc.

[1, 2, 3].reduce((acc, n) => acc + n, 0);
// 1 + 2 + 3 = 6
Enter fullscreen mode Exit fullscreen mode

El formato le parece confuso a mucha gente. Pero en realidad es muy similar a cómo lo haríamos con un bucle for:

// con un bucle for
const nums = [1, 2, 3];
let VALOR_INICIAL = 0;
let ACUMULADO = VALOR_INICIAL;

for (let i = 0; i < nums.length; i++) {
    const num = nums[i];
    ACUMULADO = ACUMULADO + num;
}
Enter fullscreen mode Exit fullscreen mode

Con reduce

[1, 2, 3].reduce((ACUMULADO, num) => ACUMULADO + num, 0 /* ← VALOR_INICIAL */);
Enter fullscreen mode Exit fullscreen mode

En el segundo parámetro del reduce ponemos el VALOR_INICIAL.

La función que pasamos como primer parámetro siempre devuelve el nuevo valor ACUMULADO. Es equivalente al interior del bucle for anterior, pero en lugar de establecer el valor ACUMULADO lo devuelve.

Podemos convertir un array de propiedades a un objeto tipo diccionario mediante un reduce:

const properties = [
  { key: "color", value: "#FF00F0" },
  { key: "size", value: 4 },
];
const dictionary = properties.reduce(
  (acc, { key, value }) => ({ ...acc, [key]: value }),
  {} /* ← VALOR_INICIAL */
);
// dictionary = {color: '#FF00F0', size: 4}
Enter fullscreen mode Exit fullscreen mode

Pero la potencia de estos métodos es su concatenación. Al concatenarlos podemos definir un pipeline de proceso de datos que va ajustando el array en pasos pequeños hasta obtener el valor deseado.

Por ejemplo podríamos obtener el total de un pedido de esta forma:

const total = order.products
  .filter((p) => !p.isFree) // remove promotional free items
  .map((p) => p.num * p.price) // multiply the price * num of items
  .reduce((acc, amount) => acc + amount); // sum all the amounts
Enter fullscreen mode Exit fullscreen mode

¡A ponerlo en práctica!

El ejercicio final tiene que ver con inmutabilidad y React. Seguro que lo resuelves

Ejercicio 2 en CodeSandbox

ver solución
Solución Ejercicio 2 en CodeSandbox

Siguiente - Cierre →

Top comments (0)