One place for hosting & domains

      Cuatro métodos para realizar búsqueda a través de matrices en JavaScript


      En JavaScript, hay muchas maneras útiles de encontrar elementos en matrices. Siempre puede recurrir al bucle básico for, pero con ES6+ hay muchos métodos para recorrer la matriz y encontrar lo que necesita con facilidad.

      Con tantos métodos diferentes, ¿cuál se debería utilizar y en qué caso? Por ejemplo, al realizar una búsqueda en una matriz, ¿quiere saber si un elemento específico está en la matriz? ¿Necesita el índice del elemento o el elemento en sí?

      Con cada método diferente que cubriremos, es importante comprender que todos estos métodos están integrados en Array.prototype. Eso significa que simplemente necesita encadenarlos a cualquier matriz con notación de punto. Esto también significa que estos métodos no están disponibles en objetos o cualquier otra cosa que no sean matrices (aunque hay superposición con cadenas).

      Observemos los siguientes métodos de matriz:

      includes

      const alligator = ["thick scales", 80, "4 foot tail", "rounded snout"];
      
      alligator.includes("thick scales"); // returns true
      

      El método .includes() devuelve un valor booleano y es ideal para indicarle si un elemento existe o no en una matriz. Da una simple respuesta de verdadero true o falso false. Esta es la sintaxis básica:

      arr.includes(valueToFind, [fromIndex]);
      

      Como ve en nuestro ejemplo, solo obtuvimos un parámetro: valueToFind. Este es el valor que debe coincidir en la matriz. El valor opcional fromIndex es un número que indica qué índice debería comenzar a buscar (por defecto es 0, por lo que realiza una búsqueda en toda la matriz). Por lo tanto, dado que en nuestro ejemplo el elemento ‘thick scales’ está en el índice 0, lo siguiente sería falso: alligator.includes('thick scales', 1); ya que comienza a buscar desde el índice 1 en adelante.

      Ahora, hay algunas cosas importantes a tener en cuenta. Este método .includes() utiliza una comparación estricta. Eso significa que, del ejemplo anterior, lo siguiente debería devolver falso: alligator.includes('80'); eso se debe a que aunque 80 == '80' es verdadero, 80 === '80' es falso: diferentes tipos no pasarán la comparación estricta.

      find

      ¿Cuál es la diferencia entre los métodos .find() e includes()? Si en nuestro ejemplo solo cambiamos el texto “includes” por “find”, obtendremos este error:

      Uncaught TypeError: thick scales is not a function
      

      Eso se debe a que el método find requiere una función para ser aprobado. Esto se debe a que el método find no usa solo el operador de comparación simple como en el caso del método “includes()”. En vez de eso, pasará cada elemento a su función y verá si devuelve verdadero o falso. Aunque esto funcione: alligator.find(() => 'thick scales');, probablemente sea recomendable poner su propio operador de comparación en la función para que devuelva cualquier valor relevante.

      const alligator = ["thick scales", 80, "4 foot tail", "rounded snout"];
      
      alligator.find(el => el.length < 12); // returns '4 foot tail'
      

      Esta sencilla función en nuestro método find busca cada elemento de la matriz, con el alias de ‘el’ que se le asigne y se detiene cuando encuentra el primero que sea verdadero. En nuestro caso, verdadero tiene una propiedad de longitud inferior a 12 (los números no tienen una propiedad de longitud). Por supuesto, puede hacer que esta función sea tan compleja como sea necesario, haciendo que su condición de verdadero se ajuste a sus necesidades.

      Observe también que esto no devolvió true. El método find no devuelve un booleano, pero en vez de eso devuelve el primer elemento que coincida. Si no hay un elemento que coincida, ya que no hay nada que cumpla con los criterios definidos en su función, devolverá undefined. También tenga en cuenta que devuelve solo la primera coincidencia, por lo que si hay más de un elemento en la matriz que cumpla con los criterios, solo obtendrá la primera de ellas. En nuestro ejemplo, si hubiera otra cadena de longitud inferior a 12 después de ‘4 foot tall’, no cambiaría nuestro resultado.

      En nuestro ejemplo, solo usamos la devolución de llamada con un parámetro. También puede añadir parámetros para hacer referencia al índice del elemento actual. Otro parámetro puede ser toda la matriz por sí misma, pero se usa de manera muy poco frecuente. Aquí hay un ejemplo usando el índice:

      alligator.find((el, idx) => typeof el === "string" && idx === 2); // returns '4 foot tall'
      

      Sabemos que en nuestra matriz, hay 3 elementos diferentes que cumplen la primera condición (typeof el === ‘string’). Si esa fuera nuestra única condición, devolverá la primera, ‘thick scales’. Pero la diferencia es que solo uno tiene el índice de 2, es decir ‘4 foot tall’.

      Hablando de índices, un método de matriz similar es .findIndex(). Este método también recibe una función, pero como se podrá imaginar, devuelve el índice del elemento que coincida en vez del elemento en sí.

      indexOf

      const alligator = ["thick scales", 80, "4 foot tail", "rounded snout"];
      
      alligator.indexOf("rounded snout"); // returns 3
      

      Al igual que el método .includes(), .indexOf() utiliza una comparación estricta, no una función como en el caso del método .find(). Pero, a diferencia de includes(), devuelve el índice del elemento, en vez de un booleano. También puede indicar a partir de qué índice en la matriz comenzar a buscar.

      indexOf() es un método muy útil. Es rápido y fácil, puede decirle dónde se encuentra el elemento en la matriz y puede indicar si dicho elemento existe. ¿Cómo le indica si el elemento existe? Básicamente, podemos saber que el elemento existe si devuelve un número positivo y si devuelve -1, indicaría que el elemento no existe.

      alligator.indexOf("soft and fluffy"); // returns -1
      alligator.indexOf(80); // returns 1
      alligator.indexOf(80, 2); // returns -1
      

      Como se puede ver, si bien podríamos usar los métodos find() o findIndex() para darnos la misma información, en este método se escribe mucho menos. No tenemos que escribir una función para realizar la comparación, ya que ya está dentro del método indexOf.

      Al igual que los demás métodos, indexOf() también devuelve el índice del primer elemento que encuentra. JavaScript nos proporciona un método de matriz alternativo .lastIndexOf(). Como se podrá imaginar, este método hace lo mismo que indexOf(), pero a partir del último índice de la matriz y funciona al revés. También puede especificar un segundo parámetro, pero recuerde que los índices no cambian solo por el hecho de usar un método diferente.

      const alligator = ["thick scales", 80, "4 foot tail", "rounded snout", 80];
      
      alligator.indexOf(80); // returns 1
      alligator.lastIndexOf(80); // returns 4
      alligator.indexOf(80, 2); // returns 4
      alligator.lastIndexOf(80, 4); // returns 4
      alligator.lastIndexOf(80, 3); // returns 1
      

      Bonus: filter

      const alligator = ["thick scales", 80, "4 foot tail", "rounded snout", 80];
      
      alligator.filter(el => el === 80); //returns [80, 80]
      

      El método filter() es como el método find(), en el sentido de que requiere una función pasada y una condición para lo que se devolverá. La principal diferencia es que filter() siempre devuelve una matriz, incluso si solo hay un elemento que coincida. Pero devolverá todos los elementos que coincidan, mientras que find() solo devuelve la primera coincidencia.

      Lo importante de filter es que devuelve todos los elementos que coinciden con sus criterios. Podría ser mi punto de vista, pero uno se podría confundir pensando “estos son los elementos que quiero filtrar out”, cuando realmente está indicando los elementos que desea filtrar in.

      Conclusión

      El método que me parece más sencillo de utilizar al realizar una búsqueda es el método find(), pero, como podrá ver, en realidad depende de su caso.

      • ¿Solo necesita saber si existe? Utilice .includes().
      • ¿Necesita obtener el elemento en sí? Utilice .find() o .filter() para buscar varios elementos.
      • ¿Necesita encontrar el índice del elemento? Utilice .indexOf() o findIndex() para realizar una búsqueda más compleja.

      Las matrices en los ejemplos presentados aquí fueron muy sencillas. Es posible que se encuentre con una matriz de objetos. A continuación, presentamos algunos ejemplos básicos para navegar por la jungla de objetos anidados:

      const jungle = [
        { name: "frog", threat: 0 },
        { name: "monkey", threat: 5 },
        { name: "gorilla", threat: 8 },
        { name: "lion", threat: 10 }
      ];
      
      // break the object down in order to use .includes() or .indexOf()
      const names = jungle.map(el => el.name); // returns ['frog', 'monkey', 'gorilla', 'lion']
      console.log(names.includes("gorilla")); // returns true
      console.log(names.indexOf("lion")); // returns 3 - which corresponds correctly assuming no sorting was done
      
      // methods we can do on the array of objects
      console.log(jungle.find(el => el.threat == 5)); // returns object - {name: "monkey", threat: 5}
      console.log(jungle.filter(el => el.threat > 5)); // returns array - [{name: "gorilla", threat: 8}, {name: 'lion', threat: 10}]
      



      Source link