js❤️ - .map, .forEach, .find, .filter, .reduce
Tags: javascript, es6, react, spanish
Published: 2022-02-05 11:17:46


## .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

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

**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

```js
planets.forEach((planet) =>
  fetch("/savePlanet", { method: "POST", body: JSON.stringify(planet) })
);
```

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

```js
roles.find(({id}) => id === 'admin')
// {id: "admin", name: "Administrator", ...}
```

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

```js
const productsOutOfStock = products.filter((product) => !product.hasStock);
```

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

```js
[1, 2, 3].reduce((acc, n) => acc + n, 0);
// 1 + 2 + 3 = 6
```

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

```js
// 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;
}
```

Con _reduce_

```js
[1, 2, 3].reduce((ACUMULADO, num) => ACUMULADO + num, 0 /* ← VALOR_INICIAL */);
```

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_:

```js
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}
```

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:

```js
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
```

## ¡A ponerlo en práctica!

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

[Ejercicio 2 en CodeSandbox](https://codesandbox.io/s/optimistic-napier-rxq4s?file=/src/UserList.js)

{% spoiler ver solución %}
[Solución Ejercicio 2 en CodeSandbox](https://codesandbox.io/s/zen-dew-oei11?file=/src/UserList.js)
{% endspoiler %}

[Siguiente - Cierre →](https://dev.to/jacarma/js-cierre-2kfa)