Volver al curso

JavaScript Desde Cero: Tu Primer Lenguaje de Programación

leccion
10 / 22
beginner
8 horas
Control de Flujo y Funciones

Métodos de Arrays Esenciales: map, filter, reduce y más

Lectura
40 min~10 min lectura

Métodos de Arrays Esenciales: map, filter, reduce y más

Objetivos de aprendizaje

Al 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
  1. Usar forEach cuando necesitás map: forEach no retorna nada. Si necesitás un nuevo array, usá map.

  2. Olvidar el return en reduce: Si tu reduce no retorna el acumulador, obtenés undefined.

  3. Mutar el array original: sort() y splice() mutan el original. Usá spread [...arr].sort() para preservarlo.

  4. No manejar el caso de array vacío: reduce sin valor inicial en un array vacío da TypeError.

  5. Encadenar demasiado sin variables intermedias: Si la cadena es muy larga, usá variables intermedias para claridad.


Puntos clave de esta lección
  1. map() transforma cada elemento y devuelve un nuevo array de la misma longitud.
  2. filter() selecciona elementos que cumplen una condición.
  3. reduce() acumula todos los elementos en un solo valor — es el más versátil.
  4. find() retorna el primer elemento que cumple la condición; findIndex() retorna su posición.
  5. some() y every() verifican condiciones sobre el array completo.
  6. Encadenar métodos permite transformaciones complejas en pocas líneas legibles.
  7. Ninguno de estos métodos muta el array original (excepto sort() y splice()).

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


💡 Concepto Clave

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" },
];
  1. Total de ingresos del mes
  2. Producto más vendido (por cantidad)
  3. Vendedor con más ingresos generados
  4. Promedio de venta por día
  5. Lista de productos únicos vendidos
  6. Ventas ordenadas de mayor a menor ingreso
🧠 Pon a prueba tu conocimiento
¿Cuál es el aspecto más importante que aprendiste en esta lección?
  • 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
✅ ¡Excelente! Continúa con la siguiente lección para profundizar más.