Métodos de Arrays Esenciales: map, filter, reduce y más
Objetivos de aprendizajeAl finalizar esta lección serás capaz de:
- Utilizar map, filter y reduce para transformar datos de forma funcional
- Aplicar find, some, every para buscar y verificar datos en arrays
- Encadenar métodos de array para realizar operaciones complejas en pocas líneas
- Elegir el método correcto según el resultado que necesitás
- Resolver problemas del mundo real con procesamiento de datos
1. Los tres métodos fundamentales: map, filter, reduce
Estos tres métodos son la base del estilo funcional en JavaScript. Los vas a usar todos los días como desarrollador.
map(): transformar cada elemento
map() crea un nuevo array aplicando una función a cada elemento del array original:
const numeros = [1, 2, 3, 4, 5];
// Duplicar cada número
const dobles = numeros.map(n => n * 2);
console.log(dobles); // [2, 4, 6, 8, 10]
// El array original NO cambia
console.log(numeros); // [1, 2, 3, 4, 5]
// Transformar datos de una forma a otra
const usuarios = [
{ nombre: "Ana", apellido: "García", edad: 28 },
{ nombre: "Carlos", apellido: "López", edad: 35 },
{ nombre: "María", apellido: "Pérez", edad: 22 },
];
// Extraer solo nombres completos
const nombresCompletos = usuarios.map(u => `${u.nombre} ${u.apellido}`);
console.log(nombresCompletos); // ["Ana García", "Carlos López", "María Pérez"]
// Agregar propiedades
const usuariosConId = usuarios.map((u, index) => ({
...u,
id: index + 1,
nombreCompleto: `${u.nombre} ${u.apellido}`,
esMayorDe30: u.edad > 30
}));
console.table(usuariosConId);
// Formatear precios
const precios = [10.5, 23.1, 99.99, 5.0];
const preciosFormateados = precios.map(p => `$${p.toFixed(2)}`);
console.log(preciosFormateados); // ["$10.50", "$23.10", "$99.99", "$5.00"]
filter(): seleccionar elementos que cumplan una condición
filter() crea un nuevo array solo con los elementos que pasen la prueba de la función:
const numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Solo pares
const pares = numeros.filter(n => n % 2 === 0);
console.log(pares); // [2, 4, 6, 8, 10]
// Solo mayores a 5
const mayores = numeros.filter(n => n > 5);
console.log(mayores); // [6, 7, 8, 9, 10]
// Filtrar objetos
const productos = [
{ nombre: "Laptop", precio: 999, stock: 5 },
{ nombre: "Mouse", precio: 29, stock: 0 },
{ nombre: "Teclado", precio: 79, stock: 12 },
{ nombre: "Monitor", precio: 450, stock: 3 },
{ nombre: "Webcam", precio: 89, stock: 0 },
];
// Productos con stock
const disponibles = productos.filter(p => p.stock > 0);
console.log(disponibles.length); // 3
// Productos caros y con stock
const carosYDisponibles = productos.filter(p => p.precio > 100 && p.stock > 0);
console.log(carosYDisponibles); // [Laptop, Monitor]
// Buscar por texto
const busqueda = "tecla";
const resultados = productos.filter(p =>
p.nombre.toLowerCase().includes(busqueda.toLowerCase())
);
console.log(resultados); // [{ nombre: "Teclado", ... }]
reduce(): acumular valores
reduce() recorre el array y acumula un único resultado (un número, string, objeto, etc.):
const numeros = [1, 2, 3, 4, 5];
// Sumar todos los elementos
const suma = numeros.reduce((acumulador, actual) => acumulador + actual, 0);
console.log(suma); // 15
// ¿Cómo funciona paso a paso?
// Iteración 1: acumulador=0, actual=1 → 0+1 = 1
// Iteración 2: acumulador=1, actual=2 → 1+2 = 3
// Iteración 3: acumulador=3, actual=3 → 3+3 = 6
// Iteración 4: acumulador=6, actual=4 → 6+4 = 10
// Iteración 5: acumulador=10, actual=5 → 10+5 = 15
// Encontrar el máximo
const maximo = numeros.reduce((max, n) => n > max ? n : max, -Infinity);
console.log(maximo); // 5
// Contar ocurrencias
const frutas = ["manzana", "banana", "manzana", "cereza", "banana", "manzana"];
const conteo = frutas.reduce((acc, fruta) => {
acc[fruta] = (acc[fruta] || 0) + 1;
return acc;
}, {});
console.log(conteo); // { manzana: 3, banana: 2, cereza: 1 }
// Calcular total de un carrito
const carrito = [
{ nombre: "Café", precio: 50, cantidad: 2 },
{ nombre: "Torta", precio: 120, cantidad: 1 },
{ nombre: "Jugo", precio: 35, cantidad: 3 },
];
const total = carrito.reduce((sum, item) => sum + item.precio * item.cantidad, 0);
console.log(`Total: $${total}`); // Total: $325
// Agrupar por categoría
const productos = [
{ nombre: "Laptop", categoria: "tech" },
{ nombre: "Café", categoria: "alimentos" },
{ nombre: "Mouse", categoria: "tech" },
{ nombre: "Pan", categoria: "alimentos" },
{ nombre: "Monitor", categoria: "tech" },
];
const porCategoria = productos.reduce((grupos, prod) => {
const cat = prod.categoria;
if (!grupos[cat]) grupos[cat] = [];
grupos[cat].push(prod.nombre);
return grupos;
}, {});
console.log(porCategoria);
// { tech: ["Laptop", "Mouse", "Monitor"], alimentos: ["Café", "Pan"] }
2. Otros métodos esenciales de arrays
find() y findIndex(): buscar un elemento
const usuarios = [
{ id: 1, nombre: "Ana", activo: true },
{ id: 2, nombre: "Carlos", activo: false },
{ id: 3, nombre: "María", activo: true },
];
// find() retorna el PRIMER elemento que cumple la condición (o undefined)
const ana = usuarios.find(u => u.nombre === "Ana");
console.log(ana); // { id: 1, nombre: "Ana", activo: true }
const inexistente = usuarios.find(u => u.nombre === "Pedro");
console.log(inexistente); // undefined
// findIndex() retorna el ÍNDICE (o -1 si no encuentra)
const indiceCarlos = usuarios.findIndex(u => u.nombre === "Carlos");
console.log(indiceCarlos); // 1
some() y every(): verificar condiciones
const notas = [8, 6, 9, 4, 7];
// some(): ¿ALGUNO cumple la condición?
console.log(notas.some(n => n >= 9)); // true (hay al menos un 9+)
console.log(notas.some(n => n < 1)); // false (ninguno menor a 1)
// every(): ¿TODOS cumplen la condición?
console.log(notas.every(n => n >= 4)); // true (todos son >= 4)
console.log(notas.every(n => n >= 6)); // false (hay un 4)
// Uso práctico: validar un formulario
const campos = [
{ nombre: "email", valor: "[email protected]", valido: true },
{ nombre: "password", valor: "12345678", valido: true },
{ nombre: "nombre", valor: "", valido: false },
];
const formularioValido = campos.every(c => c.valido);
console.log(`Formulario válido: ${formularioValido}`); // false
const hayErrores = campos.some(c => !c.valido);
console.log(`Hay errores: ${hayErrores}`); // true
Otros métodos útiles
// flat(): aplanar arrays anidados
const anidado = [[1, 2], [3, 4], [5, [6, 7]]];
console.log(anidado.flat()); // [1, 2, 3, 4, 5, [6, 7]]
console.log(anidado.flat(2)); // [1, 2, 3, 4, 5, 6, 7]
console.log(anidado.flat(Infinity)); // Aplana todo
// flatMap(): map + flat en un paso
const frases = ["Hola mundo", "JavaScript es genial"];
const palabras = frases.flatMap(f => f.split(" "));
console.log(palabras); // ["Hola", "mundo", "JavaScript", "es", "genial"]
// includes(): verificar si existe un valor
const colores = ["rojo", "verde", "azul"];
console.log(colores.includes("verde")); // true
console.log(colores.includes("amarillo")); // false
// sort(): ordenar (muta el array original)
const desordenado = [3, 1, 4, 1, 5, 9, 2, 6];
const ordenado = [...desordenado].sort((a, b) => a - b); // Copia y ordena
console.log(ordenado); // [1, 1, 2, 3, 4, 5, 6, 9]
// Ordenar objetos
const productosOrdenados = [...productos].sort((a, b) => a.precio - b.precio);
// splice(): agregar/quitar en posición (MUTA el original)
const arr = ["a", "b", "c", "d"];
arr.splice(2, 0, "x"); // En posición 2, quitar 0, insertar "x"
console.log(arr); // ["a", "b", "x", "c", "d"]
3. Encadenando métodos: el poder de la composición
La verdadera potencia surge al encadenar métodos:
const pedidos = [
{ id: 1, cliente: "Ana", total: 150, estado: "entregado", fecha: "2026-01-15" },
{ id: 2, cliente: "Carlos", total: 89, estado: "cancelado", fecha: "2026-01-20" },
{ id: 3, cliente: "María", total: 320, estado: "entregado", fecha: "2026-02-01" },
{ id: 4, cliente: "Luis", total: 45, estado: "pendiente", fecha: "2026-02-10" },
{ id: 5, cliente: "Ana", total: 210, estado: "entregado", fecha: "2026-02-15" },
{ id: 6, cliente: "Carlos", total: 175, estado: "entregado", fecha: "2026-02-18" },
];
// 1. Total de ventas entregadas en febrero
const ventasFebrero = pedidos
.filter(p => p.estado === "entregado")
.filter(p => p.fecha.startsWith("2026-02"))
.reduce((sum, p) => sum + p.total, 0);
console.log(`Ventas febrero: $${ventasFebrero}`); // $705
// 2. Top 3 clientes por monto total
const topClientes = pedidos
.filter(p => p.estado === "entregado")
.reduce((acc, p) => {
acc[p.cliente] = (acc[p.cliente] || 0) + p.total;
return acc;
}, {});
const ranking = Object.entries(topClientes)
.map(([cliente, total]) => ({ cliente, total }))
.sort((a, b) => b.total - a.total)
.slice(0, 3);
console.table(ranking);
// 3. Resumen de pedidos por estado
const resumen = pedidos.reduce((acc, p) => {
acc[p.estado] = acc[p.estado] || { cantidad: 0, monto: 0 };
acc[p.estado].cantidad++;
acc[p.estado].monto += p.total;
return acc;
}, {});
console.log(resumen);
Cuándo usar cada método
| Necesito... | Método | Retorna |
|---|---|---|
| Transformar cada elemento | map() |
Nuevo array (misma longitud) |
| Filtrar elementos | filter() |
Nuevo array (igual o menor longitud) |
| Acumular en un valor | reduce() |
Cualquier valor (número, string, objeto, array) |
| Encontrar UN elemento | find() |
El elemento o undefined |
| Verificar si ALGUNO cumple | some() |
boolean |
| Verificar si TODOS cumplen | every() |
boolean |
| Ejecutar algo por cada uno | forEach() |
undefined (solo efectos secundarios) |
Errores comunes de principiantes
Usar forEach cuando necesitás map:
forEachno retorna nada. Si necesitás un nuevo array, usámap.Olvidar el return en reduce: Si tu reduce no retorna el acumulador, obtenés
undefined.Mutar el array original:
sort()ysplice()mutan el original. Usá spread[...arr].sort()para preservarlo.No manejar el caso de array vacío:
reducesin valor inicial en un array vacío da TypeError.Encadenar demasiado sin variables intermedias: Si la cadena es muy larga, usá variables intermedias para claridad.
Puntos clave de esta lección
map()transforma cada elemento y devuelve un nuevo array de la misma longitud.filter()selecciona elementos que cumplen una condición.reduce()acumula todos los elementos en un solo valor — es el más versátil.find()retorna el primer elemento que cumple la condición;findIndex()retorna su posición.some()yevery()verifican condiciones sobre el array completo.- Encadenar métodos permite transformaciones complejas en pocas líneas legibles.
- Ninguno de estos métodos muta el array original (excepto
sort()ysplice()).
Quiz de autoevaluación
1. ¿Qué retorna [1,2,3].map(n => n * 2)?
a) 12
b) [2, 4, 6]
c) [1, 2, 3]
d) 6
2. ¿Qué método usarías para obtener el primer usuario con edad > 30?
a) filter()
b) find()
c) some()
d) map()
3. ¿Cuál es el valor inicial correcto de reduce para sumar números?
a) 1
b) null
c) 0
d) []
4. ¿Qué retorna [1,2,3].every(n => n > 0)?
a) [1, 2, 3]
b) true
c) false
d) 3
5. ¿Qué método muta el array original?
a) map()
b) filter()
c) sort()
d) reduce()
Respuestas: 1-b, 2-b, 3-c, 4-b, 5-c
Revisemos los puntos más importantes de esta lección antes de continuar.
Ejercicio práctico
Misión: Dashboard de analytics
Dado el siguiente dataset de ventas, usá métodos de arrays para calcular:
const ventas = [
{ fecha: "2026-01-05", producto: "Café", cantidad: 10, precioUnitario: 50, vendedor: "Ana" },
{ fecha: "2026-01-05", producto: "Torta", cantidad: 3, precioUnitario: 120, vendedor: "Carlos" },
{ fecha: "2026-01-12", producto: "Café", cantidad: 15, precioUnitario: 50, vendedor: "Ana" },
{ fecha: "2026-01-12", producto: "Jugo", cantidad: 8, precioUnitario: 35, vendedor: "María" },
{ fecha: "2026-01-19", producto: "Torta", cantidad: 5, precioUnitario: 120, vendedor: "Ana" },
{ fecha: "2026-01-19", producto: "Café", cantidad: 20, precioUnitario: 50, vendedor: "Carlos" },
{ fecha: "2026-01-26", producto: "Jugo", cantidad: 12, precioUnitario: 35, vendedor: "María" },
{ fecha: "2026-01-26", producto: "Café", cantidad: 18, precioUnitario: 50, vendedor: "Ana" },
];
- Total de ingresos del mes
- Producto más vendido (por cantidad)
- Vendedor con más ingresos generados
- Promedio de venta por día
- Lista de productos únicos vendidos
- Ventas ordenadas de mayor a menor ingreso
- Comprendo el concepto principal y puedo explicarlo con mis palabras
- Entiendo cómo aplicarlo en mi situación específica
- Necesito repasar algunas partes antes de continuar
- Quiero ver más ejemplos prácticos del tema