# 1.- Array functions
Así como tenemos un conjunto de métodos para realizar sobre variables que sean u otro conjunto de métodos para variables que sean , existe una serie de métodos que podemos utilizar sobre variables que sean de tipo . Son las llamadas array functions que veremos a continuación.
# Array functions que podemos encontrarnos en Javascript:
.forEach(cb, arg) //Realiza la operación definida en cb por cada elemento del array.
.every(cb, arg) //Comprueba si todos los elementos del array cumplen la condición de cb.
.some(cb, arg) //Comprueba si al menos un elem. del array cumple la condición de cb.
.map(cb, arg) //Construye un array con lo que devuelve cb por cada elemento del array.
.filter(cb, arg) //Construye un array con los elementos que cumplen el filtro de cb.
.findIndex(cb, arg) //Devuelve la posición del elemento que cumple la condición de cb.
.find(cb, arg) // Devuelve el elemento que cumple la condición de cb.
.reduce(cb, arg) //Ejecuta cb con cada elemento (de izq a der), acumulando el resultado.
.reduceRight(cb, arg) //Idem al anterior, pero en orden de derecha a izquierda.
# forEach (Cada uno)
Como se puede ver, el método forEach() no devuelve nada y espera que se le pase por parámetro una que se ejecutará por cada elemento del array. Esa función, puede ser pasada en cualquiera de los formatos que hemos visto: como función tradicional o como función flecha:
const arr = ["a", "b", "c", "d"];
// Con funciones por expresión
const f = function () {
console.log("Un elemento.");
};
arr.forEach(f);
// Con funciones anónimas
arr.forEach(function () {
console.log("Un elemento.");
});
// Con funciones flecha
arr.forEach(() => console.log("Un elemento."));
Sin embargo, este ejemplo no tiene demasiada utilidad. A la callback se le pueden pasar varios parámetros opcionales:
Si se le pasa un primer parámetro, este será el elemento del array. Si se le pasa un segundo parámetro, este será la posición en el array. Si se le pasa un tercer parámetro, este será el array en cuestión. Veamos un ejemplo:
const arr = ["a", "b", "c", "d"];
arr.forEach((e) => console.log(e)); // Devuelve 'a' / 'b' / 'c' / 'd'
arr.forEach((e, i) => console.log(e, i)); // Devuelve 'a' 0 / 'b' 1 / 'c' 2 / 'd' 3
arr.forEach((e, i, a) => console.log(a[0])); // Devuelve 'a' / 'a' / 'a' / 'a'
# every (Todos)
El método every() permite comprobar si todos y cada uno de los elementos de un array cumplen la condición que se especifique en la callback:
const arr = ["a", "b", "c", "d"];
arr.every((e) => e.length == 1); // true
En este caso, la magia está en el callback. La condición es que la longitud de cada elemento del array sea 1. Si dicha función devuelve true, significa que cumple la condición, si devuelve false, no la cumple. Por lo tanto, si todos los elementos del array devuelven true, entonces every() devolverá true.
Si expandimos el ejemplo anterior a un código más detallado, tendríamos el siguiente ejemplo equivalente, que quizás sea más comprensible para entenderlo:
const arr = ["a", "b", "c", "d"];
// Esta función se ejecuta por cada elemento del array
const todos = function (e) {
// Si el tamaño del string es igual a 1
if (e.length == 1) return true;
else return false;
};
arr.every(todos); // Le pasamos la función callback todos() a every
# some (Al menos uno)
De la misma forma que el método anterior sirve para comprobar si todos los elementos del array cumplen una determinada condición, con some() podemos comprobar si al menos uno de los elementos del array, cumplen dicha condición definida por el callback.
const arr = ["a", "bb", "c", "d"];
arr.some((e) => e.length == 2); // true
Observa que en este ejemplo, el método some() devuelve true porque existe al menos un elemento del array con una longitud de 2 carácteres.
# map (Transformaciones)
El método map() es un método muy potente y útil para trabajar con arrays, puesto que su objetivo es devolver un nuevo array donde cada uno de sus elementos será lo que devuelva la función callback por cada uno de los elementos del array original:
const arr = ["Ana", "Pablo", "Pedro", "Pancracio", "Heriberto"];
const nuevoArr = arr.map((e) => e.length);
nuevoArr; // Devuelve [3, 5, 5, 9, 9]
Observa que el array devuelto por map() es nuevoArr, y cada uno de los elementos que lo componente, es el número devuelto por el callback (e.length), que no es otra cosa sino el tamaño de cada .
Este método nos permite hacer multitud de operaciones, ya que donde devolvemos e.length podriamos devolver el propio modificado o cualquier otra cosa.
# filter (Filtrado)
El método filter() nos permite filtrar los elementos de un array y devolver un nuevo array con sólo los elementos que queramos. Para ello, utilizaremos la función callback para establecer una condición que devuelve true sólo en los elementos que nos interesen:
const arr = ["Ana", "Pablo", "Pedro", "Pancracio", "Heriberto"];
const nuevoArr = arr.filter((e) => e[0] == "P");
nuevoArr; // Devuelve ['Pablo', 'Pedro', 'Pancracio']
En este ejemplo, filtramos sólo los elementos en los que su primera letra sea P. Por lo tanto, la variable nuevoArr será un array con sólo esos elementos.
Ten en cuenta que si ningún elemento cumple la condición, filter() devuelve un vacío.
# find (Búsqueda)
En ECMAScript 6 se introducen dos nuevos métodos dentro de las Array functions: find() y findIndex(). Ambos se utilizan para buscar elementos de un array mediante una condición, la diferencia es que el primero devuelve el elemento mientras que el segundo devuelve su posición en el array original. Veamos como funcionan:
const arr = ["Ana", "Pablo", "Pedro", "Pancracio", "Heriberto"];
arr.find((e) => e.length == 5); // 'Pablo'
arr.findIndex((e) => e.length == 5); // 1
La condición que hemos utilizado en este ejemplo es buscar el elemento que tiene 5 carácteres de longitud. Al buscarlo en el array original, el primero que encontramos es Pablo, puesto que find() devolverá 'Pablo' y findIndex() devolverá 1, que es la segunda posición del array donde se encuentra.
En el caso de no encontrar ningún elemento que cumpla la condición, find() devolverá , mientras que findIndex(), que debe devolver un , devolverá -1.
# reduce (Acumuladores)
Por último, nos encontramos con una pareja de métodos denominados reduce() y reduceRight(). Ambos métodos se encargan de recorrer todos los elementos del array, e ir acumulando sus valores (o alguna operación diferente) y sumarlo todo, para devolver su resultado final.
En este par de métodos, encontraremos una primera diferencia en su función callback, puesto que en lugar de tener los clásicos parámetros opcionales (e, i, a) que hemos utilizado hasta ahora, tiene (p, e, i, a), donde vemos que aparece un primer parámetro extra inicial: p.
En la primera iteración, p contiene el valor del primer elemento del array y e del segundo. En siguientes iteraciones, p es el acumulador que contiene lo que devolvió el callback en la iteración anterior, mientras que e es el siguiente elemento del array, y así sucesivamente. Veamos un ejemplo para entenderlo:
const arr = [95, 5, 25, 10, 25];
arr.reduce((p, e) => {
console.log(`P=${p} e=${e}`);
return p + e;
});
// P=95 e=5 (1ª iteración: elemento 1: 95 + elemento 2: 5) = 100
// P=100 e=25 (2ª iteración: 100 + elemento 3: 25) = 125
// P=125 e=10 (3ª iteración: 125 + elemento 4: 10) = 135
// P=135 e=25 (4ª iteración: 135 + elemento 5: 25) = 160
// Finalmente, devuelve 160
Gracias a esto, podemos utilizar el método reduce() como acumulador de elementos de izquierda a derecha y reduceRight() como acumulador de elementos de derecha a izquierda. Veamos un ejemplo de cada uno, realizando una resta en lugar de una suma:
const arr = [95, 5, 25, 10, 25];
arr.reduce((p, e) => p - e); // 95 - 5 - 25 - 10 - 25. Devuelve 30
arr.reduceRight((p, e) => p - e); // 25 - 10 - 25 - 5 - 95. Devuelve -110
# Iteradores
En ECMAScript 6 se introducen unos métodos muy útiles para utilizar como iteradores (objetos preparados para recorrer los elementos de un array y devolver información). Hablamos de los métodos keys(), values() y entries(). El primero de ellos permite avanzar en un array, mientras va devolviendo las posiciones, el segundo los valores (el elemento en sí) y el tercero devuelve un array con la posición en el primer elemento y el valor en el segundo elemento.
.keys() //Permite iterar un array e ir devolviendo sus índices o posiciones (keys).
.values() //Permite iterar un array e ir devolviendo sus valores (elementos).
.entries() //Permite iterar un array e ir devolviendo un array [índice, valor].
Estos métodos, combinados con un for...of por ejemplo, permiten recorrer los arrays y obtener diferente información del array rápidamente. En el siguiente ejemplo utilizamos una característica avanzada que veremos más adelante llamada desestructuración:
const arr = ["Sonic", "Mario", "Luigi"];
// Obtiene un array con las keys (posiciones)
const keys = [...arr.keys()]; // [0, 1, 2]
// Obtiene un array con los valores (elementos)
const values = [...arr.values()]; // ['Sonic', 'Mario', 'Luigi']
// Obtiene un array con las entradas (par key, valor)
const entries = [...arr.entries()]; // [[0, 'Sonic'], [1, 'Mario'], [2, 'Luigi']]