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) // -> trueEs 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) // -> falseTodos 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) // -> trueEl 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) // -> trueEn 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) // -> undefinedDe 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]) // -> -10Si 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) // -> -1Resumen: así buscan find, findIndex, some y every#
Todos recorren el array en orden y se detienen en cuanto tienen la respuesta:
findIndex devuelve el índice 3, some devuelve true y every, false: falla ya con el 13.Y para elegir rápido, quédate con qué recibe y qué devuelve cada uno:
| Método | Le pasas | Devuelve | Si no hay suerte |
|---|---|---|---|
indexOf | Un elemento | Su índice | -1 |
includes | Un elemento | true | false |
some | Una función | true si alguno cumple | false |
every | Una función | true si todos cumplen | false |
find | Una función | El primer elemento que cumple | undefined |
findIndex | Una función | El índice del primero que cumple | -1 |
En resumen
- Para buscar un valor exacto:
indexOfte da su posición eincludeste dice si está. - Para buscar con una condición, pasas una función que devuelve un booleano.
somepregunta si alguno la cumple yeverysi la cumplen todos.finddevuelve el elemento yfindIndexsu índice; si no lo encuentran,undefinedy-1.some,every,findyfindIndexdejan de iterar en cuanto tienen la respuesta.