Conceptos básicos de JS: Array#filter
Sergio Daniel Xalambrí
Posted on February 8, 2019
Publicado originalmente en https://sdx.im/articles/js-basics/array-prototype-filter
Array#filter, o Array.prototype.filter
, es un método que poseen todos lo arrays en JavaScript. Este método nos sirve para filter un array y obtener uno nuevo, lo que en palabras más normales significa que vamos a recorrer un array y aplicar una condición a cada uno de sus elementos y solo quedarnos con los que pasen. Veamos un ejemplo:
const numbers = [1,2,3];
const evens = numbers.filter(number => number % 2 === 0); // es par
console.log(evens); // [2]
Lo que hace Array#filter entonces es llamar la función que pasamos como argumento una vez por cada elemento del array.
Nota: Ya que Array#filter devuelve un nuevo array, es una mala práctica usarlo para modificar manualmente el array inicial o hacer algún otro efecto al recorrer el array, para eso es mejor usar Array#forEach.
Si queremos hacer lo mismo que Array#filter tendríamos que hacer algo similar a esto:
const numbers = [1,2,3];
const evens = [];
for (const number of numbers) {
if (number % 2 === 0) evens.push(number);
}
console.log(evens); // [2,4,6]
Tendríamos que crear un nuevo array vacío, recorrer el primero e ir haciendo Array#push de cada valor que pase nuestra condición
Sintaxis
La sintaxis completa de la función es la siguiente
const result = initial.filter(function callback(currentValue, index, array) {
// Devuelve true o false para saber si debe quedarse o no
}, thisArg);
Array#filer recibe dos argumentos, una función callback
y un valor, cualquiera, que va a ser asignado como this
del callback, en caso de usar arrow functions este valor no hace nada. El callback a su vez recibe tres argumentos, la mayoría de las veces se suele usar solo el primero y algunas veces el segundo, el primero es el valor actual por el que estamos pasando en la iteración, el segundo es el índice dentro de nuestro array y el tercero es el mismo array que estamos iterando.
Por último, la función devuelve un nuevo array con los resultados de haber ejecutado callback
una vez por cada elemento del array inicial.
Implementando Array#filter a mano
Veamos ahora como crear nuestro propio Array#filter para entender mejor su funcionamiento. Vamos a implementarlo como una función llamada filter
cuyo primer valor va a ser el array
a filtear y después vamos a recibir el callback
y el valor de this
.
function map(array, callback, thisArg) {
const result = [];
const boundCallback = thisArg ? callback.bind(thisArg) : callback;
for (let index = 0; index < array.length; index++) {
if (boundCallback(array[index], index, array)) result.push();
}
return result;
}
const numbers = [1,2,3];
const evens = filter(numbers, number => number % 2 === 0);
console.log(evens); // [2,4,6]
¿Qué es lo que hicimos? Nuestra función recibe los tres argumentos que dijimos antes, luego crea un array vacío llamado result
y una constante llamada boundCallback
que en caso de que se haya definido thisArg
es igual a hacer Function#bind de callback
con el valor de thisArg
y en caso contrario es igual a callback
. Después iteramos el array inicial y hacemos result.push
si el valor que devuelve callback
es true
, al cual le pasamos el valor actual del array, el índice y el array entero. Por último devolvemos el resultado.
Casos de uso
Array#filter es usado un montón en JavaScript, especialmente cuando se trabaja de una forma funcional y en combinación con otros métodos como Array#map. Es usado en React.js para filtras listas de datos en elementos de React, por ejemplo:
function List({ list, query }) {
return (
<ul>
{list
.filter(item => item.content.includes(query))
.map(item => <Item key={item.id} {...item} />)
}
</ul>
);
}
ReactDOM.render(
<List list={[{ id: 1, content: "hola" }, { id: 2, content: }]} query="hola" />,
target
);
Este componente List
usa Array#filter para filtrar según el contenido de cada elemento y Array#map para transformar cada item
que queda después del filtro del array list
en el elemento devuelto por el componente Item
pasándole toda la información de cada item
al componente.
Fuera de React puede ser usado también para trabajar con listas de elementos del DOM.
const $selectList = document.querySelectorAll("select");
const values = Array
.from($selectList)
.map($select => $select.value)
.filter(value => value !== "")
Lo que hace el ejemplo es obtener todos los <select>
de una página lo que devuelve un objeto NodeList, usando Array.from
lo convertimos a un array y usamos Array#map para obtener una lista (values
) de los valores de cada <select>
, por último con Array#filter eliminamos los valores igual a un string vacío, que podría ser considerado la opción por defecto.
Palabras finales
Este método es muy útil y es usado a diario al trabajar con Arrays en JavaScript. Si no lo habías usado antes te recomiendo probar varios ejemplos de uso para familiarizarte, cuando lo hagas vas a querer usarlo siempre, especialmente en combinación de Array#map y Array#reduce.
Posted on February 8, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.