Array functions

Así como tenemos un conjunto de métodos para realizar sobre variables que sean String u otro conjunto de métodos para variables que sean Number, existe una serie de métodos que podemos utilizar sobre variables que sean de tipo Array. Son las llamadas array functions que veremos a continuación.

¿Qué son las Array functions?

Básicamente, son métodos que tiene cualquier variable que sea de tipo Array, y que permite realizar una operación con todos los elementos de dicho array para conseguir un objetivo concreto, dependiendo del método. En general, a dichos métodos se les pasa por parámetro una función callback y unos parámetros opcionales.

Estas son las Array functions que podemos encontrarnos en Javascript:

Método Descripción
Undefined .forEach(cb, arg) Realiza la operación definida en cb por cada elemento del array.
Boolean .every(cb, arg) Comprueba si todos los elementos del array cumplen la condición de cb.
Boolean .some(cb, arg) Comprueba si al menos un elemento del array cumple la condición de cb.
Array .map(cb, arg) Construye un array con lo que devuelve cb por cada elemento del array.
Array .filter(cb, arg) Construye un array con los elementos que cumplen el filtro de cb.
Number .findIndex(cb, arg) Devuelve la posición del elemento que cumple la condición de cb.
Object .find(cb, arg) Devuelve el elemento que cumple la condición de cb.
Object .reduce(cb, arg) Ejecuta cb con cada elemento (de izq a der), acumulando el resultado.
Object .reduceRight(cb, arg) Idem al anterior, pero en orden de derecha a izquierda.

A grandes rasgos, a cada uno de estos métodos se les pasa una función callback que se ejecutará por cada uno de los elementos que contiene el array. Empecemos por forEach(), que es quizás el más sencillo de todos.

Cada uno

Como se puede ver, el método forEach() no devuelve nada y espera que se le pase por parámetro una Function 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:

var arr = ['a', 'b', 'c', 'd'];

// Con funciones por expresión
var 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 Function 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:

var 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'

En este ejemplo, he nombrado e al parámetro que hará referencia al elemento, i al parámetro que hará referencia al índice (posición del array) y a al parámetro que hará referencia al array en cuestión. Aún así, el usuario puede ponerle a estos parámetros el nombre que prefiera. Como se puede ver, realmente forEach() es otra forma de hacer un bucle (sobre un array), sin tener que recurrir a bucles tradicionales como for o while.

Como vemos en la tabla anterior, al método forEach() se le puede pasar un segundo parámetro arg, que representa el valor que sobreescribiría a la palabra clave this en el código dentro de la función callback. De necesitar esta funcionalidad, recuerda que no puedes utilizar las funciones flecha, ya que el this no tiene efecto en ellas.

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 Function callback:

var 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 String 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:

var arr = ['a', 'b', 'c', 'd'];

// Esta función se ejecuta por cada elemento del array
var 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

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.

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

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:

var arr = ['Ana', 'Pablo', 'Pedro', 'Pancracio', 'Heriberto'];
var 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 String.

Este método nos permite hacer multitud de operaciones, ya que donde devolvemos e.length podriamos devolver el propio String modificado o cualquier otra cosa.

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:

var arr = ['Ana', 'Pablo', 'Pedro', 'Pancracio', 'Heriberto'];
var 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 Array vacío.

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:

var 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á Undefined, mientras que findIndex(), que debe devolver un Number, devolverá -1.

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:

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

var 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

Recuerda que en cualquiera de estas array functions puedes realizar operaciones o condiciones tanto con el parámetro e (elemento), como con el parámetro i (índice o posición) o con el parámetro a (array).

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.

Método Descripción
Arrayi .keys() Permite iterar un array e ir devolviendo sus índices o posiciones (keys).
Arrayi .values() Permite iterar un array e ir devolviendo sus valores (elementos).
Arrayi .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:

var arr = ['Sonic', 'Mario', 'Luigi'];

// Obtiene un array con las keys (posiciones)
var keys = [...arr.keys()];         // [0, 1, 2]

// Obtiene un array con los valores (elementos)
var values = [...arr.values()];     // ['Sonic', 'Mario', 'Luigi']

// Obtiene un array con las entradas (par key, valor)
var entries = [...arr.entries()];   // [[0, 'Sonic'], [1, 'Mario'], [2, 'Luigi']]
Manz
Publicado por Manz

Docente, divulgador informático y freelance. Escribe en Emezeta.com, es profesor en la Oficina de Software Libre de la Universidad de La Laguna y dirige el curso de Programación web FullStack de EOI en Tenerife (Canarias). En sus ratos libres, busca GIF de gatos en Internet.