Four Methods to Search Through Arrays in JavaScript

In JavaScript, there are plenty of useful ways to find items in Arrays. You could always resort to the basic for loop, but with ES6+ there are plenty of methods to loop over the array and find what you need with ease.

With so many different methods, which one do you use and in which case? For instance, when searching through an array, do you want to know if the element is in the array at all? Do you need the index of the element or the element itself?

With each different method that we’ll cover, it’s important to understand that they’re all built-in methods on the Array.prototype. That means you simply need to chain them onto any array with dot notation. That also means these methods are not available on objects or anything else other than Arrays (though there is overlap with Strings).

We’ll look at the following Array methods:

includes

const alligator = ["thick scales", 80, "4 foot tail", "rounded snout"];

alligator.includes("thick scales"); // returns true

The .includes() method returns a boolean value and is perfect for telling you whether an element exists in an array or not. It gives a simple true or false answer. This is the basic syntax:

arr.includes(valueToFind, [fromIndex]);

Now as you see in our example, we only had one parameter – the valueToFind. This is the value to match in the array. The optional fromIndex is a number, indicating what index you want to start looking from (default is 0, so the entire array is searched). So, since in our example the ‘thick scales’ item is at the 0 index, the following would be false: alligator.includes('thick scales', 1); since it starts searching from index 1 and on.

Now, there are a few important things to notice. This .includes() method uses strict comparison. That means, from the example above, the following would return false: alligator.includes('80'); That’s because though 80 == '80' is true, 80 === '80' is false – different types won’t pass strict comparison.

find

How is .find() different from the includes() method? If in our example we only changed the text “includes” to “find” we would get this error:

Uncaught TypeError: thick scales is not a function

That’s because the find method requires a function to be passed in. That’s because the find method isn’t going to just use the simple comparison operator like “includes()” does. Instead, it will pass each element into your function and see whether it returns true or false. So, although this works: alligator.find(() => 'thick scales');, you would probably want to put your own comparison operator in the function for it to return anything relevant.

const alligator = ["thick scales", 80, "4 foot tail", "rounded snout"];

alligator.find(el => el.length < 12); // returns '4 foot tail'

This simple function in our find method looks at each element of the array, with the alias of ‘el’ we assigned it, and stops when it finds the first one which is true. In our case, true is having a length property of less than 12 (numbers don’t have a length property). You could of course make this function as complex as needed, making your true condition meet your needs.

Notice as well, this didn’t return true. The find method doesn’t return a boolean, but instead returns the first matching element. If there isn’t a matching element – as in nothing exists that meets the criteria defined in your function – it will return undefined. Also notice that it returns the first, so if there is more than one element in the array that meets the criteria, it will only grab the first instance. In our example, if there was another string of length less than 12 after ‘4 feet tall’ it wouldn’t change our result.

In our example, we only employed the callback with one parameter. You can also add parameters to reference the current element’s index. Another parameter can be the entire array itself, but I find this rarely used. Here is an example using the index:

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

We know in our array, there are 3 different elements that meet the first condition (typeof el === ‘string’). If this was our only condition, it would return the first one, ‘thick scales’. But the difference is, only one has the index of 2 and that is ‘4 foot tall’.

Speaking of indexes, a similar array method is .findIndex(). This method also receives a function, but as you can guess, it returns the matching element’s index instead of the element itself.

indexOf

const alligator = ["thick scales", 80, "4 foot tail", "rounded snout"];

alligator.indexOf("rounded snout"); // returns 3

Like the .includes() method, .indexOf() uses strict comparison, not a function as we saw with the .find() method. But, unlike includes(), it returns the index of the element, rather than a boolean. You can also indicate which index in the array to start searching at.

I find indexOf() to be very useful. It’s quick and easy, can tell you where the element is in the array, and can tell you whether the element exists. How does it tell you if the element exists? Basically, we can know the element exists if it returns a positive number, and if it returns -1 we know the element doesn’t exist.

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

And as you can see, although we could get the find() or findIndex() methods to give us the same information, this is a whole lot less to write. We don’t have to write out a function for comparison, as it is already within the indexOf method.

Now, like the others, indexOf() also returns the index of the first matching element it finds. JavaScript gives us an alternate array method .lastIndexOf(). As you can guess, this does the same thing as indexOf() but starting from the last index of the array and working backward. You can also specify a second parameter, but remember the indexes don’t change, just because you are using a different method.

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]

The filter() method is like the find() method, in that it requires a function passed and a condition for what will be returned. The main difference is, filter() always returns an array, even if there is only one matching element. But it will return all the matching elements, whereas find() only returns the first matching.

The important thing with filter is that it returns all the elements matching your criteria. It could only be me, but I can get confused, thinking “these are the elements I want to filter out”, when truthfully, you are indicating the elements you wish to filter in.

Conclusion

The easiest method I find to use, when searching for something is the find() method, but as you can see it really depends on your case.

  • Do you need to know only if it exists? Use .includes().
  • Do you need to get the element itself? Use .find(), or .filter() for multiple items.
  • Do you need to find the index of the element? Use .indexOf() or findIndex() for a more complex search.

The arrays in the examples here were very simple. You may find yourself with an array of objects. Here are some very basic examples below to navigate through the jungle of nested objects:

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}]

Originally posted on DigitalOcean Community Tutorials
Author: Stephen Hartfield

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *