Saltar al contenido principal
04Arrays

Buscar en Arrays

Clase 4 de 88 min de lectura

Tarde o temprano vas a tener un array y una pregunta: ¿está este elemento?, ¿dónde?, ¿hay alguno que cumpla tal condición? Podrías responderlas con un bucle, pero JavaScript ya trae un método para cada pregunta: indexOf, includes, some, every, find y findIndex.

Se parecen bastante, y lo que los distingue es qué preguntan y qué devuelven. Vamos uno a uno, empezando con este array de emojis:

const emojis = ['✨', '🥑', '😍']

indexOf: ¿En qué posición está el elemento?#

Le pasas un elemento y te devuelve su índice dentro del array. Si el elemento no existe, devuelve -1.

const emojis = ['✨', '🥑', '😍']const posicionCorazon = emojis.indexOf('😍')console.log(posicionCorazon) // -> 2

¿Por qué -1 y no 0 o false? Porque 0 es una posición válida, la del primer elemento. El -1 es la forma de decir «no está» sin confundirse con ningún índice real.

includes: ¿El elemento existe en el Array?#

Si la posición te da igual y solo quieres saber si el elemento está, includes responde directamente con true o false.

const emojis = ['✨', '🥑', '😍']const tieneCorazon = emojis.includes('😍')console.log(tieneCorazon) // -> true

Es la forma más corta y sencilla de buscar un elemento concreto. El límite llega cuando no buscas un valor exacto, sino un elemento que cumpla una condición. Para eso están los métodos que vienen ahora.

some: ¿Alguno de los elementos cumple con la condición?#

El método some comprueba si al menos un elemento del array cumple una condición.

La condición se la das en forma de función. Esa función recibe cada elemento del array y debe devolver un booleano. En cuanto uno devuelve true, some devuelve true; si ninguno lo hace, devuelve false.

const emojis = ['✨', '🥑', '😍']const tieneCorazon = emojis.some(emoji => emoji === '😍')console.log(tieneCorazon) // -> true

¡Pero si esto ya lo podíamos hacer con includes! Sí, pero some es mucho más potente, porque la función puede comprobar lo que tú quieras. Por ejemplo, si en el array hay algún nombre de más de 3 caracteres:

const names = ['Leo', 'Isa', 'Ían', 'Lea']const tieneNombreLargo = names.some(name => name.length > 3)console.log(tieneNombreLargo) // -> false

Todos los nombres tienen exactamente 3 letras, así que ninguno pasa la prueba.

Un detalle importante: some deja de iterar en cuanto encuentra un elemento que cumple la condición. No tiene sentido seguir si ya sabe la respuesta. Compruébalo con un console.log dentro de la función:

const numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]const tieneNumeroMayorA5 = numbers.some(number => {  // Imprime solo hasta el número 6  console.log(`Estoy iterando sobre el número ${number}`)  return number > 5})console.log(tieneNumeroMayorA5) // -> true

El 6 es el primero mayor que 5. Ahí some ya tiene su respuesta y ni se molesta en mirar el 7, el 8 y el 9.

every: ¿Todos los elementos cumplen con la condición?#

every es el hermano exigente de some: no le vale con que uno cumpla la condición, tienen que cumplirla todos.

Se usa igual. Le pasas una función que recibe el elemento de cada vuelta y devuelve un booleano. Si todos devuelven true, every devuelve true; con que uno solo devuelva false, el resultado es false.

// ¿Todos los emojis son felices?const emojis = ['😀', '😂', '😍', '😭', '🥺', '😎']const todosSonFelices = emojis.every(emoji => emoji === '😀')console.log(todosSonFelices) // -> false// ¿Todos los números son pares?const numbers = [2, 4, 7, 10, 12]const todosSonPares = numbers.every(number => number % 2 === 0)console.log(todosSonPares) // -> false// ¿Todos los strings son mayores a 3 caracteres?const names = ['Miguel', 'Juan', 'Itziar', 'Isabel']const todosLosNombresSonLargos = names.every(name => name.length > 3)console.log(todosLosNombresSonLargos) // -> true

En el segundo ejemplo, el 7 lo estropea todo. Y como pasaba con some, every también corta por lo sano: deja de iterar en cuanto encuentra un elemento que no cumple la condición.

find: Devuelve el primer elemento que cumple con la condición#

Hasta ahora las respuestas eran true o false. Pero ¿y si lo que quieres es el elemento? Eso hace find: te devuelve el primer elemento que cumple la condición, no un booleano.

El funcionamiento es el mismo: le pasas una función que devuelve un booleano.

const numbers = [13, 27, 44, -10, 81]// encuentra el primer número negativoconst firstNegativeNumber = numbers.find(number => number < 0)console.log(firstNegativeNumber) // -> -10

¿Y si ninguno la cumple? Entonces find devuelve undefined:

const numbers = [13, 27, 44, 81]// encuentra el primer número negativoconst firstNegativeNumber = numbers.find(number => number < 0)console.log(firstNegativeNumber) // -> undefined

De nuevo, igual que some y every, find deja de iterar en cuanto encuentra lo que busca.

findIndex: Devuelve el índice del primer elemento que cumple con la condición#

findIndex es igual que find, pero en lugar del elemento te devuelve su índice. Con ese índice puedes, por ejemplo, acceder después al elemento:

const numbers = [13, 27, 44, -10, 81]// encuentra el índice del primer número negativoconst firstNegativeNumberIndex = numbers.findIndex(number => number < 0)console.log(firstNegativeNumberIndex) // -> 3// ahora puedes usar el índice para acceder al elementoconsole.log(numbers[firstNegativeNumberIndex]) // -> -10

Si ningún elemento cumple la condición, devuelve -1, igual que hacía indexOf:

const numbers = [13, 27, 44, 81]// encuentra el índice del primer número negativoconst firstNegativeNumberIndex = numbers.findIndex(number => number < 0)console.log(firstNegativeNumberIndex) // -> -1

Resumen: así buscan find, findIndex, some y every#

Todos recorren el array en orden y se detienen en cuanto tienen la respuesta:

Infografía
Cómo busca find (y cuándo se detiene)
6.Con la misma condición, findIndex devuelve el índice 3, some devuelve true y every, false: falla ya con el 13.
Paso 6 de 6

Y para elegir rápido, quédate con qué recibe y qué devuelve cada uno:

MétodoLe pasasDevuelveSi no hay suerte
indexOfUn elementoSu índice-1
includesUn elementotruefalse
someUna funcióntrue si alguno cumplefalse
everyUna funcióntrue si todos cumplenfalse
findUna funciónEl primer elemento que cumpleundefined
findIndexUna funciónEl índice del primero que cumple-1

En resumen

  • Para buscar un valor exacto: indexOf te da su posición e includes te dice si está.
  • Para buscar con una condición, pasas una función que devuelve un booleano.
  • some pregunta si alguno la cumple y every si la cumplen todos.
  • find devuelve el elemento y findIndex su índice; si no lo encuentran, undefined y -1.
  • some, every, find y findIndex dejan de iterar en cuanto tienen la respuesta.