"El diseño es el embajador silencioso de tu marca"
- Paul Brand

Iterar con map, filter y reduce

Hoy vamos a hablar sobre como Iterar con map, filter y reduce (hace tiempo escribí un artículo sobre como Iterar con jQuery each, la función de iteración de la famosa librería de Javascript).

Si ya estas usando jQuery o Lodash para iterar sobre arrays te preguntarás que diferencia hay entre lo que haces ahora y usar estas funciones, ambas tienen ventajas e inconvenientes.

En el caso de usar librerías te ahorras tener que mirar si tu navegador soporta esos métodos, también podría tener particularidades que ya conozcamos y sean útiles, como que el each de jQuery tambien te permite iterar sobre los atributos de un objeto. A veces usamos librerías simplemente porque estamos acostumbrados a ellas y conocemos bien su sintaxis, aunque esto no es una ventaja de por si.

Por contra usar librerías te obliga a tener que cargarlas, aumentamos el peso de la web y nos atamos nuestro código a ellas. Obviamente no es malo usar alguna librería como estas que mencionamos pero siempre está bien saber como se usan los metodos nativos, que implementados o no por los navegadores, ya forman parte del estandar.

Para que os animeis a usarlo, mencionaros que realmente son métodos que llevan ya bastante tiempo entre nosotros (de hecho su estandar es ES5), y estan soportados por todos los navegadores modernos, os dejo la imagen de caniuse por si alguien no se fía (vale para los 3 métodos).

El método map

El método map nos permite iterar sobre un array y realizar transformaciones sobre él. Llegados a este punto la pregunta que igual te surge es para que quiero un método que haga esto si yo ya tengo el bucle for, o incluso el método forEach que tambien son nativos y ya me sirven.

Antes de nada, comentar que obviamente podemos realizar una iteración usando cualquiera de estos tres métodos, y que también podemos hacer transformaciones sobre los elementos del array. El punto es que no funcionan igual y según los casos puede ser más eficiente usar una u otro.

Esto lo podemos ver más claro usando un ejemplo. Pongamos que tenemos un array de objetos con modelos de coches, y queremos ir iterando sobre este array y guardar en otro array un texto que contenga la marca y el modelo…

Este es el array.

Con el bucle for de toda la vida haríamos algo así.

Esto funciona y hace lo que dijimos arriba, veamos ahora como sería usando un forEach.

Hacer esto es exactamente lo mismo que arriba, pero tiene ventajas como que es mucho más legible y facil de mantener porque nos evita tener que mantener el control de los indices.

Y ahora veamos como hacemos con el método map.

La principal diferencia entre map y forEach que además es la responsable de todas sus ventajas es que mientras que forEach devuelve undefined teniendo que usar su función de callback para hacer la lógica, map retorna ya el producto final, o dicho de otra manera, devuelve el array con las modificaciones que le hagamos en la función de callback.

Gracias a esto con map podemos mapear directamente la variable cars_names contra el método map, y tambien nos ahorramos tener que usar el metodo push para irla rellenando en cada iteracion, algo muy útil.

Es importante recordar que esa función de callback de map tenga un return como vemos arriba, o sino nos va a devolver un array con todos sus elementos en undefined.

Otra ventaja que tiene map frente a forEach, que al devolver el array modificado podríamos encadenarla con otras funciones.

Antes de continuar, esa diferencia que comentabamos de que devuelve algo apoyandose en la función de callback, y que por tanto se puede asignar directamente y es encadenable, aplica también a los métodos filter y reduce, ya no lo voy a comentar cuando hable de ellos pero tenedlo en cuenta.

La salida que producen todos estos casos equivale a:

 

El método filter

Mientras que con map tenemos un array modificado con filter tenemos un array filtrado, es decir, en vez de devolver un array con el mismo número de elementos pero modificados, devolvemos el array pero sin algunos elementos y sin modificarlos.

Pensemos en que tenemos el mismo array que antes pero que queremos filtrar la marca Seat.

En este caso la función de callback tambien necesita tener un return, pero no se usa para lo mismo, en el map el return modificaba el elemento sobre el que iteraba, en filter el return es un booleano que indica si el elemento es filtrado o no.

En nuestro caso hemos puesto como expresion car.brand !== 'Seat', es decir que cuando llegue una marca que no sea Seat será evaluado a true y ese elemento será devuelto, pero cuando sea Seat evalua a false y es filtrado.

La salida que produce equivale a:

 

El método reduce

El útimo método es reduce y es el más dificil de entender de las 3.

Mientras que los otros métodos devolvían un array, el método reduce devuelve un solo valor y no una colección, de ahí su nombre porque reduce un array a un valor.

Tiene dos argumentos, la función de callback como en los otros casos y un valor inicial que se usar para arrancar en la primera llamada.

La función de callback tambien tiene distintos argumentos  ya no es el elemento del array (y opcionalmente el indice y el array), sino que son:

  1. Valor anterior
  2. Valor actual
  3. Índice actual (opcional)
  4. Array sobre el que usaste reduce (opcional)

El ejemplo más sencillo que podemos hacer con este método es el de sumar todos los elementos de un array de números, pensemos en que tenemos esto:

Y ahora uso reduce para reducirlos a un solo valor que sea la suma de todos…

La variable total ahora vale 44

 

Aunque en todos los ejemplos que he usado aquí empleo ES5 no quiere decir que no puedas usar estos métodos usando una sintaxis más moderna como el ES6, por ejemplo en la función map podría haber usado la interpolación de cadenas para concatenar las variables, y las funciones de callback podrían haber sido arrow functions, pero esta entrada era solo para hablar de estos métodos y no quise hacerlo así.

 

The following two tabs change content below.
Especialista en diseño web responsive, programador html5, css3, jquery, php y java.

Latest posts by Óscar Lijó (see all)