Cómo Obtener el Último Valor Coincidente de un Array en JavaScript
Necesitas encontrar el último elemento en un array que cumpla una condición. Tal vez sea el registro de error más reciente, la última entrada válida de un formulario o el último usuario que estuvo activo. Antes de ES2023, esto significaba soluciones incómodas: invertir arrays, filtrar todo o escribir bucles manuales. Ahora hay una forma más limpia.
Puntos Clave
- Usa
findLast()para recuperar el último elemento del array que coincida con una condición sin mutar el array original. - Usa
findLastIndex()cuando necesites la posición en lugar del valor en sí. - Evita usar
reverse().find()ya que muta el array original e introduce errores sutiles. - Recuerda los diferentes valores de retorno:
findLast()devuelveundefinedcuando no se encuentra ninguna coincidencia, mientras quefindLastIndex()devuelve-1.
La Solución Moderna: Array.prototype.findLast()
Array.prototype.findLast() itera hacia atrás a través de un array y devuelve el primer elemento que satisface tu predicado. Es el espejo de find(), que busca desde el inicio.
const logs = [
{ type: 'info', message: 'Started' },
{ type: 'error', message: 'Connection failed' },
{ type: 'info', message: 'Retrying' },
{ type: 'error', message: 'Timeout' }
]
const lastError = logs.findLast(log => log.type === 'error')
// { type: 'error', message: 'Timeout' }
Si ningún elemento coincide, findLast() devuelve undefined. Esto hace que sea seguro usarlo con encadenamiento opcional:
const lastError = logs.findLast(log => log.type === 'critical')?.message ?? 'No critical errors'
findLast vs findLastIndex: Cuando Necesitas la Posición
A veces necesitas el índice, no el valor. Eso es lo que proporciona findLastIndex(). Devuelve el índice del último elemento coincidente, o -1 si nada coincide.
const numbers = [1, 5, 3, 8, 2, 9, 4]
const lastLargeIndex = numbers.findLastIndex(n => n > 7)
// 5 (el índice de 9)
Usa findLastIndex() cuando necesites hacer splice, slice desde esa posición o referenciar elementos vecinos.
Compatibilidad con Navegadores y Alternativas
Tanto findLast() como findLastIndex() son parte de ES2023 y tienen amplio soporte en navegadores modernos y versiones recientes de Node.js. Sin embargo, los entornos más antiguos pueden no incluirlos.
Si TypeScript se queja de estos métodos, tu tsconfig.json probablemente necesita "lib": ["ES2023"] o más reciente en las opciones del compilador.
Para entornos sin soporte nativo, aquí hay una alternativa limpia que no muta el array original:
function findLast(arr, predicate) {
for (let i = arr.length - 1; i >= 0; i--) {
if (predicate(arr[i], i, arr)) {
return arr[i]
}
}
return undefined
}
Este bucle inverso es eficiente: se detiene en la primera coincidencia y evita crear arrays intermedios.
Discover how at OpenReplay.com.
Errores Comunes a Evitar
No inviertas el array para usar find():
// ❌ ¡Muta el array original!
const last = arr.reverse().find(x => x > 5)
// ✅ Usa findLast en su lugar
const last = arr.findLast(x => x > 5)
Llamar a reverse() modifica tu array en su lugar. Esto crea errores sutiles que son difíciles de depurar.
No confundas los valores de retorno:
findLast()devuelve el elemento oundefinedfindLastIndex()devuelve el índice o-1
Verificar la veracidad funciona para findLast(), pero con findLastIndex() debes verificar explícitamente -1:
const index = arr.findLastIndex(x => x > 100)
if (index !== -1) {
// Lo encontró
}
Ten cuidado con las coincidencias falsas:
Si tu array contiene 0, false o cadenas vacías, asegúrate de que tu predicado las maneje correctamente:
const values = [1, 2, 0, false, 'last']
values.findLast(x => x) // 'last' (omite valores falsos)
values.findLast(() => true) // 'last' (obtiene el último elemento real)
Cuándo Elegir Cada Enfoque
| Necesidad | Método |
|---|---|
| Último elemento que coincida con una condición | findLast() |
| Índice del último elemento coincidente | findLastIndex() |
| Último elemento simple (sin condición) | arr.at(-1) o arr[arr.length - 1] |
| Búsqueda de valor exacto | lastIndexOf() |
Conclusión
Para obtener el último valor coincidente de un array en JavaScript, recurre primero a findLast(). Es legible, no muta tus datos y se detiene tan pronto como encuentra una coincidencia. Cuando necesites la posición en lugar del valor, usa findLastIndex(). Para entornos más antiguos, un simple bucle inverso proporciona una alternativa confiable sin los riesgos de mutación de reverse(). Mantén tus predicados explícitos y recuerda los diferentes valores de retorno—undefined versus -1—para evitar fallos silenciosos.
Preguntas Frecuentes
Sí, findLast() funciona en arrays dispersos. Itera hacia atrás a través del array y omite los espacios vacíos, invocando el predicado solo para los elementos que realmente existen. Este comportamiento refleja cómo find() maneja los arrays dispersos al iterar hacia adelante.
findLast() es más eficiente porque deja de iterar tan pronto como encuentra una coincidencia. Usar filter().pop() procesa todo el array primero, creando un nuevo array en memoria, y luego recupera el último elemento. Para arrays grandes, findLast() ofrece ganancias significativas de rendimiento.
Sí, findLast() soporta genéricos de TypeScript y el estrechamiento de tipos. Cuando usas un type guard como tu predicado, TypeScript infiere correctamente el tipo estrechado para el elemento devuelto. Asegúrate de que tu tsconfig.json incluya ES2023 en el array lib para las definiciones de tipos adecuadas.
Sí, puedes agregar un polyfill a Array.prototype si el método no existe. Primero verifica la existencia del método, luego asigna una función que itere hacia atrás a través del array. Core-js y otras bibliotecas de polyfill también proporcionan implementaciones listas para usar para una compatibilidad más amplia.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.