Métodos Filter y Reduce en JavaScript: Uso y Ejemplos Prácticos
Resumen
Dominar los métodos filter y reduce es fundamental para trabajar con arrays en JavaScript de forma limpia y funcional. Ambos comparten una característica esencial: no modifican el array original, sino que generan un nuevo valor a partir de él. Entender cómo funcionan abre la puerta a manipulaciones de datos elegantes y eficientes.
¿Cómo funciona filter para obtener solo los elementos que necesitas?
El método filter recorre cada elemento de un array y evalúa una condición. Solo los elementos que cumplan esa condición formarán parte de un nuevo array [0:10]. Es como un filtro real: lo que pasa la prueba se queda, lo que no, se descarta.
Por ejemplo, dado un array de números del uno al diez, se puede obtener únicamente los números pares con esta estructura:
El operador módulo (%) devuelve el residuo de una división [1:32]. Cuando divides un número entre dos y el residuo es cero, ese número es par. Por eso number % 2 === 0 es la condición perfecta para filtrar pares.
4 % 2 devuelve 0, entonces cuatro es par.
5 % 2 devuelve 1, entonces cinco no es par.
La función dentro de filter recibe cada elemento como parámetro (en singular, por convención) y utiliza un arrow function para definir la condición de retorno [1:10].
¿Qué hace reduce y cómo transforma un array en un solo valor?
Mientras filter devuelve un array, reduce hace algo distinto: comprime todo el array en un único valor [2:22]. Su caso más clásico es sumar todos los elementos.
La función que recibe reduce trabaja con dos parámetros principales:
accumulator: actúa como una variable que va almacenando el resultado parcial en cada iteración [3:08].
currentValue: representa el elemento actual del array que se está procesando.
Además, reduce acepta un segundo argumento después de la función: el initialValue. En el ejemplo anterior es 0, lo que significa que el acumulador comienza desde cero [3:42].
¿Cómo usar reduce para contar la frecuencia de palabras?
Reduce no se limita a sumar números. Un uso poderoso es contar cuántas veces se repite cada palabra en un array [4:30]. En este caso, el valor inicial no es un número, sino un objeto vacío{}.
La primera vez que aparece una palabra, no existe en el acumulador, por lo que se le asigna el valor 1 [5:40].
Cuando la misma palabra aparece de nuevo, el condicional detecta que ya existe y le suma uno al conteo [6:18].
Al finalizar, el acumulador contiene un objeto con cada palabra como clave y su frecuencia como valor.
Este patrón es especialmente útil para análisis de datos, conteo de ocurrencias y agrupaciones sin necesidad de bucles explícitos.
¿Cuándo elegir filter y cuándo reduce?
La diferencia clave está en lo que necesitas obtener. Usa filter cuando quieras un subconjunto del array original que cumpla cierta condición. Usa reduce cuando necesites transformar todo el array en un resultado único, ya sea un número, un string o incluso un objeto complejo.
filter siempre devuelve un array.
reduce devuelve cualquier tipo de dato según el initialValue y la lógica definida.
Ambos métodos respetan la inmutabilidad del array original, lo que los convierte en herramientas esenciales dentro del paradigma de programación funcional en JavaScript. Practica combinándolos y comparte qué otros usos creativos les encuentras.
También puedes leer el resumen de esa clase si aún no lo entiendes 🚀🚀
Tanto **filter()** como **reduce()** son métodos poderosos en JavaScript que permiten manipular arrays de manera efectiva, pero tienen propósitos muy distintos.
### **1. filter()**
El método **filter()** se utiliza para **filtrar los elementos de un array** que cumplen con una condición específica. Devuelve un **nuevo array** con los elementos que pasen el filtro (es decir, aquellos para los que la función de filtro devuelva true).
**Ejemplo:**
let numbers = \[1,2,3,4,5,6];// Filtrar los números pareslet evenNumbers = numbers.filter(function(number){ return number %2===0;});console.log(evenNumbers);
**Salida:**
\[2,4,6]
**Características de filter()**:
- Devuelve un **nuevo array** con los elementos que cumplen la condición.
- No modifica el array original.
- Si ningún elemento cumple la condición, devuelve un array vacío.
### **2. reduce()**
El método **reduce()** se utiliza para **reducir** un array a un solo valor, como la suma de sus elementos, un producto, o incluso un objeto o array. Funciona aplicando una función acumulativa a los elementos del array, lo que permite obtener un resultado único basado en todos los elementos.
**Ejemplo:**
let numbers = \[1,2,3,4,5];// Sumar todos los números del arraylet sum = numbers.reduce(function(accumulator, currentValue){ return accumulator + currentValue;},0);console.log(sum);
**Salida:**
15
**Características de reduce()**:
- Devuelve un **único valor** (puede ser un número, string, objeto, array, etc.).
- Tiene un **acumulador** que almacena el resultado de cada iteración.
- Requiere un **valor inicial** (en este caso 0), que es el valor inicial del acumulador.
- Puede ser más complejo, pero es extremadamente útil para realizar operaciones como sumar, concatenar, combinar elementos, o incluso construir objetos a partir de un array.
### **Diferencias clave entre filter() y reduce()**:
- **Propósito**:
- filter() se utiliza para **filtrar** elementos de un array y devolver un nuevo array que solo contiene los elementos que cumplen la condición.
- reduce() se utiliza para **reducir** el array a un único valor acumulado (como una suma, producto o cualquier otra operación agregada).
- **Resultado**:
- filter() devuelve un **nuevo array** con los elementos que cumplen la condición.
- reduce() devuelve **un solo valor** que es el resultado de aplicar la función de acumulación.
### Ejemplo comparativo:
**filter() para filtrar números mayores a 2:**
let numbers = \[1,2,3,4,5];let filteredNumbers = numbers.filter(function(number){ return number >2;});console.log(filteredNumbers);// \[3, 4, 5]
**reduce() para sumar todos los números:**
let numbers = \[1,2,3,4,5];let sum = numbers.reduce(function(accumulator, number){ return accumulator + number;},0);console.log(sum);// 15
### **Usos típicos:**
- **filter()**:
- Para extraer elementos que cumplen ciertas condiciones.
- Ejemplo: Filtrar productos con un precio mayor a cierto valor, o filtrar estudiantes con notas superiores a un umbral.
- **reduce()**:
- Para obtener un solo valor a partir de un array.
- Ejemplo: Sumar todos los valores de un array, calcular el total de ventas, o construir un objeto a partir de un array de datos.
### Ejemplo más avanzado de reduce():
**Convertir un array de objetos en un objeto con reduce():**
let people = \[ {name:'Alice',age:25}, {name:'Bob',age:30}, {name:'Charlie',age:35}];// Crear un objeto donde los nombres son claves y las edades son valoreslet peopleObject = people.reduce(function(acc, person){  acc\[person.name]= person.age; return acc;},{});console.log(peopleObject);
**Salida:**
{Alice:25,Bob:30,Charlie:35}
### Conclusión:
- Usa **filter()** cuando necesites **extraer** elementos específicos de un array.
- Usa **reduce()** cuando necesites **agregar o combinar** todos los elementos del array en un solo valor o resultado.
Hola. De pronto le sirva a alguien nuevo.
Tuve confusiones en la parte de las letras, puesto que la profe asume implícitamente el cambio de sintáxis de manejo de array a manejo de objetos. Sin embargo, esto es lo que lo hace muy confuso; entonces.
Entregamos un objeto si, sin embargo, la sintaxis "accumulator[currentValue] no es el "accumulator en la posición currentValue" por que esta sintáxis de "posición" es exclusiva de arrays y está basada en un índice posicional. Por otro lado, lo que la profe tal vez pasa en decir es que es la clave y valor del objeto que estamos retornando. Y, por que estamos retornando un objeto ? si nos damos cuenta, ella despuesito pone como valor inicial un objeto.
por otro lado, esto:
accumulator[currentValue] = 1, nos dice que asignemos el valor de 1 a la clave "currentValue" que se encuentra en el objeto "accumulator". Y cuando usamos el condicional, estamos verificando si dicha clave existe dentro de nuestro objeto. Si existe, suma 1 valor más a dicha clave, si no existe, la crea dentro del objeto y asigna 1. Yo lo entendí así. Si soy peor de confuso, perdón.
bien, se entiende
Excelente explicación y buena onda 😎
Quiero compartir con ustedes un ejercicio "avanzado" para el uso de reduce que se me ocurrió mientras veía esta clase.
/*
El siguiente ejemplo será avanzado, tendremos un array de personas con los atributos nombre, edad y
sexo (representados por las letras F y M), y aplicaremos el método reduce() para contar la cantidad
de personas del sexo femenino, del sexo masculino y los menores de 16 años. Note el valor inicial del
acumulador, se trata de un objeto con tantos atributos para cada contador.
*/const people =[{name:'John',age:32,gender:'M',},{name:'Charlie',age:15,gender:'F',},{name:'Susan',age:10,gender:'F',},{name:'Max',age:42,gender:'M',},{name:'Louis',age:13,gender:'F',},{name:'Erika',age:18,gender:'F',},{name:'Richard',age:60,gender:'M',},{name:'Lucas',age:12,gender:'M',},{name:'Maria',age:23,gender:'F',},{name:'Angel',age:19,gender:'M',},{name:'Miriam',age:39,gender:'F',},{name:'Lina',age:48,gender:'F',},]const peopleCounterByConditions = people.reduce((counter, currentPeople)=>{if(currentPeople.gender==="F") counter.females+=1if(currentPeople.gender==="M") counter.males+=1if(currentPeople.age<16) counter.underAge+=1return counter
},{males:0,females:0,underAge:0,})console.log(people);console.log(peopleCounterByConditions);```/\* El siguiente ejemplo será avanzado, tendremos un array de personas con los atributos nombre, edad y sexo (representados por las letras F y M), y aplicaremos el método reduce() para contar la cantidad de personas del sexo femenino, del sexo masculino y los menores de 16 años. Note el valor inicial del acumulador, se trata de un objeto con tantos atributos para cada contador.\*/*const* people = \[{name:'John',age:32,gender:'M',},{name:'Charlie',age:15,gender:'F',},{name:'Susan',age:10,gender:'F',},{name:'Max',age:42,gender:'M',},{name:'Louis',age:13,gender:'F',},{name:'Erika',age:18,gender:'F',},{name:'Richard',age:60,gender:'M',},{name:'Lucas',age:12,gender:'M',},{name:'Maria',age:23,gender:'F',},{name:'Angel',age:19,gender:'M',},{name:'Miriam',age:39,gender:'F',},{name:'Lina',age:48,gender:'F',},]*const* peopleCounterByConditions = people.reduce((*counter*,*currentPeople*)*=>*{if(*currentPeople*.gender==="F")*counter*.females+=1if(*currentPeople*.gender==="M")*counter*.males+=1if(*currentPeople*.age<16)*counter*.underAge+=1return*counter*},{males:0,females:0,underAge:0,})console.log(people);console.log(peopleCounterByConditions);
Hice mi solución primero antes de ver tu código, lo tomé como reto personal, te agradezco por tu comentario, me has ayudado a profundizar.
const peopleQuantity = people.reduce((accumulator, currentValue)=>{if(currentValue.gender==='F'&& accumulator['Mujeres']){ accumulator['Mujeres']++}elseif(currentValue.gender==='F'&&!accumulator['Mujeres']){ accumulator['Mujeres']=1}if(currentValue.gender==='M'&& accumulator['Hombres']){ accumulator['Hombres']++}elseif(currentValue.gender==='M'&&!accumulator['Hombres']){ accumulator['Hombres']=1}if(currentValue.age<16&& accumulator['Menores de 16']){ accumulator['Menores de 16']++}elseif(currentValue.age<16&&!accumulator['Menores de 16']){ accumulator['Menores de 16']=1}return accumulator
},{})console.log(peopleQuantity);
Métodos de Arrays en JavaScript: Filter y Reduce
Filter
El método Filter en JavaScript se utiliza para crear un nuevo array con todos los elementos que pasan una prueba (condición) implementada por una función proporcionada.
Filter no modifica el array original.
Ejemplo de uso de Filter
Dado un array de números: [2, 4, 8, 10, 12], queremos crear un nuevo array con números mayores a 5.
En este ejemplo, wordFrequency es un objeto que muestra cuántas veces se repite cada palabra en el array original.
Sugerencia: La explicación de reduce queda algo breve. En el ejemplo de conteo ayudaría aclarar por qué el acumulador inicia como {} y no como 0 (porque necesitamos un objeto donde cada clave sea el elemento y su valor sea el conteo). Considerando que muchos toman JavaScript como primer lenguaje, ese detalle marca la diferencia.
Dicho eso, la comunidad en los comentarios complementa de maravilla: sin esos aportes, el curso se sentiría incompleto.
Recomendación: lean siempre los comentarios de cada clase; ahí encontrarán explicaciones, matices y ejemplos que consolidan el aprendizaje
Brother muchas gracias por tu comentario. Yo la verdad sigo un poco perdido en este apartado. Normalmente cuando me pasa suelo complementar con videos de YouTube.
Ahora, me da curiosidad cuando dices que muchos toman JS como primer lenguaje, y es mi caso por ejemplo, pero te quería consultar, ¿recomiendas algún otro lenguaje para empezar en programación? consulto porque me dedico principalmente al UX/UI y quiero complementar con código para ser un poco más autónomo y porque cada vez me llama más la atención la programación.
Hola! Puedes aprender más sobre estos dos métodos consultando su documentación:
📃
📃
Aquí te dejo mi versión de apuntes de esta clase!
Ustedes sabian que el typeof(NaN) es number?
A
qui dejo un ejemplo de como filtrar los numeros de un array mixto.
Puede que sirva esta explicacion para otra Persona, a mi me sirvió para entender mejor el metodo que se explica.
El Acumulador (acumulador): Es como una caja donde vas guardando el resultado parcial. Empezará con el valor que tú le digas y se irá actualizando en cada vuelta.
El Valor Actual (valorActual): Es el elemento del array que la función está procesando en ese preciso momento (el 2, luego el 3, luego el 4...).
La Operación (+): Es lo que quieres hacer. En tu caso, sumar lo que ya tienes en la caja con el número nuevo.
El Valor Inicial (0): Es el segundo argumento de .reduce(). Es el valor con el que la caja (acumulador) empieza la primera vez.
en el último ejercicio obtenemos la frecuencia de cada palabra, pero, qué pasa si la lista es grande y queremos obtener aquella palabra con mayor frecuencia (suponiendo que hay sólo una)?
Aquí les comparto mi solución:
// how many times does a word appear in a list?const words =['apple','banana','hello','bye','banana','bye','bye'];const wordFrecuency = words.reduce((acc, curr)=>{if(acc[curr]){ acc[curr]++;}else{ acc[curr]=1;}return acc;},{});console.log('words: ', words);console.log('words frecuency: ', wordFrecuency);console.log('palabra con mayor frenuencia: ',Object.entries(wordFrecuency).reduce((max, actual)=> actual[1]> max[1]? actual : max));
El último ejemplo con el reduce me dejó hecho cenizas. Venia pisteando como campeón y pasaron cosas
quedamos igual jajaj
quede igual...... ánimo bro no eres el único jeje
como cuando estas en clase y se te buguea la pagina de platzi a quien mas le paso
const notas =[65,75,7,12,97,45,86,71,75,67,82]const aprobados = notas.filter(nota=> nota >=70)// filtra todas la notas que sean mayor o igual a 70const promedio = aprobados.reduce((suma, nota)=> suma + nota,0)/ aprobados.length// suma las notas aprobadas y saca el promedio.console.log(aprobados)console.log(promedio)
En el texto de esta clase el segundo ejemplo esta incompleto, debería estar de la forma: