map, filter y reduce: domina los arrays en JavaScript

Los arrays son la columna vertebral de cualquier aplicación web y, gracias a los métodos map, filter y reduce, podemos manipularlos de manera declarativa y legible. En este artículo veremos cómo funcionan, cuándo usarlos y algunos trucos para sacarle el máximo partido.
¿Por qué usar los métodos funcionales?
En lugar de escribir bucles for tradicionales, estos métodos nos permiten describir qué queremos obtener del array, no cómo hacerlo. El resultado suele ser código más corto, menos propenso a errores y más fácil de testear.
El método map
map crea un nuevo array aplicando una función a cada elemento del original. Es ideal cuando quieres transformar los datos sin mutar el array fuente.
const numbers = [1, 2, 3, 4];
const squares = numbers.map(num => num * num);
console.log(squares); // [1, 4, 9, 16]
Observa que numbers sigue intacto; map devuelve siempre un nuevo array.
El método filter
filter devuelve otro array con los elementos que cumplen una condición. Es la herramienta perfecta para “seleccionar” datos.
const users = [
{name: 'Ana', active: true},
{name: 'Luis', active: false},
{name: 'María', active: true}
];
const activeUsers = users.filter(u => u.active);
console.log(activeUsers);
// [{name: 'Ana', active: true}, {name: 'María', active: true}]
Al igual que map, filter no modifica el array original.
El método reduce
reduce es el más potente y a la vez el más abstracto. Permite condensar un array en un único valor (número, objeto, cadena, etc.) mediante una función acumuladora.
const prices = [19.99, 9.99, 4.99];
const total = prices.reduce((acc, price) => acc + price, 0);
console.log(total); // 34.97
El segundo argumento (0) es el valor inicial del acumulador. Sin él, reduce usaría el primer elemento del array como partida.
Combinando los tres métodos
Una de las grandes ventajas es que podemos encadenarlos para crear pipelines de transformación claros.
const orders = [
{id: 1, amount: 250, paid: true},
{id: 2, amount: 75, paid: false},
{id: 3, amount: 120, paid: true}
];
const totalPaid = orders
.filter(o => o.paid)
.map(o => o.amount)
.reduce((sum, v) => sum + v, 0);
console.log(totalPaid); // 370
En este ejemplo filtramos los pedidos pagados, extraemos solo el importe y finalmente sumamos todos los valores.
Buenas prácticas y trucos
- Evita mutar dentro de los callbacks. Si modificas el elemento original, perderás la ventaja de la inmutabilidad.
- Prefiere funciones puras. Un callback que depende de variables externas puede producir resultados inesperados.
- Usa
reducecon moderación. Cuando el objetivo es simplemente obtener la suma o el máximo, a veces un bucleforresulta más rápido. - Reutiliza funciones. Declara la lógica de transformación en funciones nombradas y pásalas a
mapofilterpara mejorar la legibilidad.
Rendimiento: ¿cuándo preocuparse?
En la mayoría de los casos la diferencia de rendimiento entre estos métodos y un bucle tradicional es despreciable. Sin embargo, si trabajas con arrays gigantes (más de 100 000 elementos) y ejecutas varias pasadas, considera:
- Combinar operaciones en un solo
reducepara evitar crear arrays intermedios. - Usar
for…ofowhilecuando el coste de creación de funciones anónimas sea crítico.
Conclusión
Dominar map, filter y reduce te permite escribir código más expresivo y menos propenso a errores. Practica con datos reales, combina los métodos y observa cómo tu lógica se vuelve más declarativa. ¡A experimentar y a seguir aprendiendo!