Más allá de map, filter y reduce, JavaScript ofrece métodos de array especializados que resuelven tareas concretas de forma más expresiva. Conocer cuál usar en cada situación evita implementaciones manuales innecesarias y bugs sutiles.
find() y findIndex(): buscar el primer elemento
find(fn) devuelve el primer elemento para el que fn devuelve verdadero, o undefined si no lo encuentra. findIndex(fn) devuelve el índice de ese elemento, o -1:
const usuarios = [
{ id: 1, nombre: 'Ana', activo: true },
{ id: 2, nombre: 'Luis', activo: false },
{ id: 3, nombre: 'Sara', activo: true }
];
// find: devuelve el objeto, no solo un valor
const usuarioActivo = usuarios.find(u => u.activo);
console.log(usuarioActivo); // { id: 1, nombre: 'Ana', activo: true }
const porId = usuarios.find(u => u.id === 2);
console.log(porId?.nombre); // 'Luis'
const noExiste = usuarios.find(u => u.id === 99);
console.log(noExiste); // undefined
// findIndex: para obtener posición y poder splice/update
const indice = usuarios.findIndex(u => u.id === 2);
console.log(indice); // 1
// Diferencia clave con filter:
// find ? primer elemento encontrado (o undefined)
// filter ? todos los elementos que cumplen (o [])
const activos = usuarios.filter(u => u.activo);
console.log(activos.length); // 2
findLast() y findLastIndex(): buscar desde el final
ES2023 añadió las versiones que recorren el array de atrás hacia adelante:
const logs = [
{ nivel: 'info', msg: 'Inicio' },
{ nivel: 'error', msg: 'Fallo conexión' },
{ nivel: 'info', msg: 'Reintento' },
{ nivel: 'error', msg: 'Timeout' },
{ nivel: 'info', msg: 'OK' }
];
// Último error registrado
const ultimoError = logs.findLast(l => l.nivel === 'error');
console.log(ultimoError.msg); // 'Timeout'
const indiceUltimoError = logs.findLastIndex(l => l.nivel === 'error');
console.log(indiceUltimoError); // 3
some() y every(): comprobar condiciones
some(fn) devuelve true si al menos un elemento cumple la condición. every(fn) devuelve true solo si todos la cumplen. Ambos hacen cortocircuito:
const edades = [22, 17, 30, 15, 25];
// ¿Hay algún menor?
const hayMenores = edades.some(edad => edad < 18);
console.log(hayMenores); // true
// ¿Son todos mayores de edad?
const todosMayores = edades.every(edad => edad >= 18);
console.log(todosMayores); // false
// Casos con array vacío (importante para lógica booleana):
[].some(x => x > 0); // false (vacío ? ninguno cumple)
[].every(x => x > 0); // true (vacío ? todos cumplen, vacuamente)
// Ejemplo real: validación de formulario
const campos = [
{ nombre: 'email', valor: '[email protected]', valido: true },
{ nombre: 'pass', valor: '1234', valido: false },
{ nombre: 'nombre', valor: 'Ana', valido: true }
];
const formularioValido = campos.every(c => c.valido);
const hayErrores = campos.some(c => !c.valido);
console.log(formularioValido); // false
console.log(hayErrores); // true
flat() y flatMap(): aplanar arrays anidados
flat(profundidad) crea un nuevo array con los sub-arrays aplanados hasta la profundidad indicada. flatMap(fn) es equivalente a map(fn).flat(1) pero más eficiente:
// flat(): aplanar arrays anidados
const anidado = [1, [2, 3], [4, [5, 6]]];
console.log(anidado.flat()); // [1, 2, 3, 4, [5, 6]] profundidad 1
console.log(anidado.flat(2)); // [1, 2, 3, 4, 5, 6]
console.log(anidado.flat(Infinity)); // siempre aplanado del todo
// Eliminar huecos (slots vacíos) en arrays
const conHuecos = [1, , 3, , 5];
console.log(conHuecos.flat()); // [1, 3, 5]
// flatMap(): mapear y aplanar un nivel
const frases = ['Hola mundo', 'JavaScript es genial'];
const palabras = frases.flatMap(f => f.split(' '));
console.log(palabras); // ['Hola', 'mundo', 'JavaScript', 'es', 'genial']
// Caso real: expandir etiquetas de artículos
const articulos = [
{ titulo: 'JS Moderno', etiquetas: ['js', 'es6', 'web'] },
{ titulo: 'Node.js', etiquetas: ['js', 'node', 'backend'] }
];
const todasEtiquetas = articulos.flatMap(a => a.etiquetas);
console.log([...new Set(todasEtiquetas)]);
// ['js', 'es6', 'web', 'node', 'backend']
El TypeError más frecuente
Llamar a estos métodos sobre un valor que no es array es el error más común. Suele ocurrir al trabajar con datos de API que no siempre devuelven lo esperado:
// Si la API devuelve null en lugar de array:
const datos = null;
datos.find(x => x.id === 1); // TypeError: Cannot read properties of null
// Protección básica:
const resultado = (datos ?? []).find(x => x.id === 1);
// O verificar antes:
if (Array.isArray(datos)) {
const item = datos.find(x => x.id === 1);
}
La elección entre estos métodos depende de lo que necesites: usa find cuando buscas un elemento, some cuando solo necesitas saber si existe, every para validaciones globales y flatMap cuando cada elemento del array puede generar cero o más elementos en el resultado.
