Métodos de array en JavaScript: map, filter, reduce, find, sort y más

Los métodos que vas a usar en cada proyecto: cuándo usar cada uno, cómo funcionan por dentro y los errores que todo el mundo comete al empezar.

Cuando aprendes JavaScript, los arrays son de lo primero que tocas. Pero durante un tiempo, la única herramienta que usas para trabajar con ellos es el bucle for. Para transformar datos, para buscar un elemento, para sumar valores — todo con for.

El problema no es que funcione mal. Es que hace el código más largo, más difícil de leer y más fácil de romper. JavaScript tiene métodos de array específicos para cada una de esas operaciones, y una vez que los integras en tu forma de trabajar, el for se queda para los casos en que realmente lo necesitas.

En este artículo están los que más vas a usar: map, filter, reduce, find, sort, includes, push, pop y splice. Con ejemplos reales y los errores que la mayoría comete al empezar con cada uno.

map(): transformar cada elemento

map() recorre el array y aplica una función a cada elemento, devolviendo un array nuevo con los resultados. El array original no se toca. El nuevo siempre tiene el mismo número de elementos que el original.

El uso más habitual es convertir datos de una forma a otra. Por ejemplo, tienes un array de precios sin IVA y necesitas mostrarlos con IVA:

JavaScript 📋
const preciosSinIVA = [100, 250, 80, 420];

const preciosConIVA = preciosSinIVA.map(precio => precio * 1.21);

console.log(preciosConIVA); // [121, 302.5, 96.8, 508.2]
console.log(preciosSinIVA); // [100, 250, 80, 420] — sin tocar

También funciona con arrays de objetos, que es lo más habitual cuando trabajas con datos de una API:

JavaScript 📋
const usuarios = [
    { id: 1, nombre: 'Ana', activo: true },
    { id: 2, nombre: 'Luis', activo: false },
    { id: 3, nombre: 'Carla', activo: true }
];

// Extraer solo los nombres
const nombres = usuarios.map(u => u.nombre);
console.log(nombres); // ['Ana', 'Luis', 'Carla']

// O transformar el objeto entero
const resumen = usuarios.map(u => ({
    id: u.id,
    etiqueta: `${u.nombre} — ${u.activo ? 'activo' : 'inactivo'}`
}));

El error más común con map() es usarlo cuando en realidad no necesitas el array nuevo — solo quieres ejecutar algo por cada elemento. Para eso está forEach(). map() tiene sentido cuando vas a usar el array que devuelve.

filter(): quedarse con los que cumplen una condición

filter() recorre el array y devuelve uno nuevo con solo los elementos para los que la función devuelve true. El array resultante puede tener menos elementos que el original, o incluso estar vacío si ninguno pasa el filtro.

JavaScript 📋
const productos = [
    { nombre: 'Laptop', precio: 1200, enStock: true },
    { nombre: 'Teclado', precio: 150, enStock: true },
    { nombre: 'Monitor', precio: 800, enStock: false },
    { nombre: 'Ratón', precio: 45, enStock: true }
];

// Solo los que están en stock y cuestan menos de 200€
const disponiblesBaratos = productos.filter(p => p.enStock && p.precio < 200);

console.log(disponiblesBaratos);
// [{ nombre: 'Teclado', ... }, { nombre: 'Ratón', ... }]

Un uso que sorprende la primera vez: eliminar duplicados de un array. Funciona usando el índice que filter() pasa como segundo parámetro:

JavaScript — eliminar duplicados 📋
const numeros = [10, 20, 10, 30, 20, 40];

const unicos = numeros.filter((valor, index, array) => {
    return array.indexOf(valor) === index;
});

console.log(unicos); // [10, 20, 30, 40]

// indexOf siempre devuelve el primer índice donde aparece el valor.
// Si el índice actual no coincide con el primero, es un duplicado.

Para eliminar duplicados en proyectos reales, Set es más limpio: [...new Set(numeros)]. Pero entender cómo funciona con filter() te ayuda a ver cómo los métodos acceden al array completo.

find(): el primero que cumpla la condición

find() es como filter() pero para cuando solo necesitas un elemento, no todos. Devuelve el primer elemento que pasa la prueba y para ahí. Si ninguno la pasa, devuelve undefined.

JavaScript 📋
const usuarios = [
    { id: 1, nombre: 'Ana', rol: 'admin' },
    { id: 2, nombre: 'Luis', rol: 'editor' },
    { id: 3, nombre: 'Carla', rol: 'editor' }
];

const admin = usuarios.find(u => u.rol === 'admin');
console.log(admin); // { id: 1, nombre: 'Ana', rol: 'admin' }

const noExiste = usuarios.find(u => u.rol === 'superadmin');
console.log(noExiste); // undefined

El error típico aquí es no comprobar si el resultado es undefined antes de usarlo. Si haces admin.nombre y admin es undefined, tu código peta con un TypeError. Siempre comprueba:

JavaScript 📋
const usuario = usuarios.find(u => u.id === 99);

// ❌ Esto peta si usuario es undefined
console.log(usuario.nombre);

// ✅ Comprueba antes
if (usuario) {
    console.log(usuario.nombre);
}

// ✅ O con optional chaining
console.log(usuario?.nombre); // undefined sin error

También existe findIndex(), que devuelve el índice en vez del elemento. Útil cuando necesitas luego eliminar o reemplazar ese elemento en el array.

sort(): ordenar arrays

sort() es el que más confunde al principio porque su comportamiento por defecto es contraintuitivo. Sin argumentos, convierte los elementos a string y los ordena alfabéticamente. Eso funciona para letras, pero con números da resultados raros:

JavaScript — el error clásico de sort 📋
const numeros = [10, 1, 21, 2, 100];

// ❌ Sin función comparadora — ordena como strings
console.log(numeros.sort());
// [1, 10, 100, 2, 21] — mal

// ✅ Con función comparadora para números
console.log(numeros.sort((a, b) => a - b));
// [1, 2, 10, 21, 100] — bien (ascendente)

console.log(numeros.sort((a, b) => b - a));
// [100, 21, 10, 2, 1] — bien (descendente)

La función comparadora recibe dos elementos (a y b) y decide su orden según el valor que devuelve: negativo pone a antes, positivo pone b antes, cero los deja igual.

Para ordenar objetos por una propiedad:

JavaScript — ordenar objetos 📋
const productos = [
    { nombre: 'Monitor', precio: 800 },
    { nombre: 'Teclado', precio: 150 },
    { nombre: 'Laptop', precio: 1200 }
];

// Por precio ascendente
productos.sort((a, b) => a.precio - b.precio);

// Por nombre alfabético
productos.sort((a, b) => a.nombre.localeCompare(b.nombre));

Ojo: sort() modifica el array original, no devuelve uno nuevo. Si necesitas mantener el orden original, haz una copia antes: [...productos].sort(...).

includes(): comprobar si un elemento existe

Esto es lo que la gente busca cuando busca "javascript array contains" — JavaScript no tiene un método contains(), se llama includes(). Devuelve true o false.

JavaScript 📋
const roles = ['admin', 'editor', 'viewer'];

console.log(roles.includes('admin'));  // true
console.log(roles.includes('superadmin')); // false

// Útil en condicionales
const rolUsuario = 'editor';
if (roles.includes(rolUsuario)) {
    console.log('Acceso permitido');
}

includes() usa comparación estricta (===), así que [1, 2, 3].includes('1') devuelve false. Si necesitas buscar objetos, mejor usa find() o some().

push(), pop(), splice(): modificar el array

Estos tres modifican el array original, a diferencia de los anteriores que devuelven arrays nuevos.

push() añade elementos al final y devuelve la nueva longitud:

JavaScript — push y pop 📋
const tareas = ['Estudiar', 'Practicar'];

tareas.push('Repasar');
console.log(tareas); // ['Estudiar', 'Practicar', 'Repasar']

// push acepta varios elementos a la vez
tareas.push('Descansar', 'Revisar');

// pop() elimina y devuelve el último elemento
const ultima = tareas.pop();
console.log(ultima); // 'Revisar'
console.log(tareas); // ['Estudiar', 'Practicar', 'Repasar', 'Descansar']

splice() es el más versátil: elimina, inserta o reemplaza elementos en cualquier posición. Su firma es splice(inicio, cuántos, ...elementos):

JavaScript — splice 📋
const frutas = ['manzana', 'plátano', 'naranja', 'fresa'];

// Eliminar 1 elemento desde el índice 1
frutas.splice(1, 1);
console.log(frutas); // ['manzana', 'naranja', 'fresa']

// Insertar sin eliminar (0 elementos a eliminar)
frutas.splice(1, 0, 'kiwi');
console.log(frutas); // ['manzana', 'kiwi', 'naranja', 'fresa']

// Reemplazar: eliminar 1 e insertar otro
frutas.splice(2, 1, 'pera');
console.log(frutas); // ['manzana', 'kiwi', 'pera', 'fresa']

El uso más habitual de splice() en proyectos reales es eliminar un elemento por su índice, que normalmente encuentras antes con findIndex():

JavaScript — eliminar elemento por id 📋
const items = [
    { id: 1, nombre: 'Laptop' },
    { id: 2, nombre: 'Teclado' },
    { id: 3, nombre: 'Ratón' }
];

const idEliminar = 2;
const indice = items.findIndex(item => item.id === idEliminar);

if (indice !== -1) {
    items.splice(indice, 1);
}

console.log(items);
// [{ id: 1, nombre: 'Laptop' }, { id: 3, nombre: 'Ratón' }]

reduce(): convertir un array en cualquier cosa

reduce() es el más potente y el que más cuesta entender al principio. La idea es simple: recorre el array acumulando un resultado, y al final devuelve ese resultado. Ese resultado puede ser un número, un string, un objeto, otro array — lo que necesites.

Recibe dos argumentos: la función reductora y el valor inicial del acumulador. El valor inicial es importante — si lo omites, reduce() usa el primer elemento como acumulador, lo que puede dar resultados inesperados con objetos.

JavaScript — reduce para sumar 📋
const carrito = [
    { producto: 'Laptop', precio: 1200, cantidad: 1 },
    { producto: 'Ratón', precio: 80, cantidad: 2 },
    { producto: 'Teclado', precio: 150, cantidad: 1 }
];

const total = carrito.reduce((acumulador, item) => {
    return acumulador + (item.precio * item.cantidad);
}, 0); // <-- valor inicial: 0

console.log(total); // 1510

Un uso menos obvio pero muy habitual: agrupar elementos por una propiedad. Esto aparece constantemente cuando trabajas con datos de APIs:

JavaScript — agrupar por propiedad 📋
const pedidos = [
    { id: 1, estado: 'pendiente', importe: 120 },
    { id: 2, estado: 'enviado', importe: 85 },
    { id: 3, estado: 'pendiente', importe: 200 },
    { id: 4, estado: 'entregado', importe: 340 }
];

const porEstado = pedidos.reduce((grupos, pedido) => {
    const estado = pedido.estado;
    if (!grupos[estado]) {
        grupos[estado] = [];
    }
    grupos[estado].push(pedido);
    return grupos;
}, {});

/*
{
  pendiente: [{ id: 1, ... }, { id: 3, ... }],
  enviado:   [{ id: 2, ... }],
  entregado: [{ id: 4, ... }]
}
*/

Encadenar métodos

Como cada método devuelve un array nuevo (excepto los que modifican el original), puedes encadenarlos. Cada uno recibe el resultado del anterior:

JavaScript — encadenamiento 📋
const inventario = [
    { nombre: 'CPU', categoria: 'Hardware', precio: 400, enStock: true },
    { nombre: 'VS Code', categoria: 'Software', precio: 0, enStock: true },
    { nombre: 'RAM', categoria: 'Hardware', precio: 120, enStock: false },
    { nombre: 'GPU', categoria: 'Hardware', precio: 900, enStock: true }
];

// Precio total del hardware en stock
const totalHardware = inventario
    .filter(item => item.categoria === 'Hardware' && item.enStock)
    .map(item => item.precio)
    .reduce((total, precio) => total + precio, 0);

console.log(totalHardware); // 1300 (400 + 900)

Cada línea describe un paso: primero filtramos, luego extraemos precios, luego sumamos. Cualquiera puede leer esto y entender qué hace sin necesidad de comentarios.

Cuándo usar cada método

map() cuando quieres transformar cada elemento y necesitas el array resultado. filter() cuando quieres un subconjunto del array original. find() cuando solo necesitas un elemento. sort() para ordenar — recuerda pasar siempre la función comparadora con números. includes() para comprobar si un valor existe. push()/pop() para añadir o quitar del final. splice() para eliminar o insertar en cualquier posición. reduce() para cuando necesitas convertir el array en algo que no es un array.

Y para recorrer sin necesitar el resultado: forEach(). Si quieres profundizar en cómo combinarlo con JSON y localStorage, tienes el tutorial de JSON y forEach para guardar datos.

JavaScript createElement: crear elementos DOM dinámicamente

El siguiente paso natural: una vez que tienes los datos procesados con estos métodos, aquí aprendes a mostrarlos en pantalla de forma segura.