Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 4

Array Searching: find(), findIndex(), and includes()

Recommended resources

Hello! Welcome to your next lesson.

In our last few lessons, we've built a solid foundation in transforming arrays. We used map() to create new arrays from existing ones, filter() to select specific elements, and reduce() to aggregate an entire array into a single result.

Today, we shift from transforming data to locating it. You'll often need to find a specific piece of data within an array—for instance, finding a user by their ID, checking if a product is already in a shopping cart, or getting the position of an item to update it.

This lesson covers three essential methods for this purpose:

  • find(): To retrieve the first element that satisfies a specific condition.
  • findIndex(): To get the index (position) of that element.
  • includes(): To quickly check if a specific value exists in an array.

By the end of this lesson, you'll be able to choose the right tool to efficiently find what you're looking for in any array.

1. The Core Idea: The Predicate Function

Before diving into find() and findIndex(), it's helpful to understand a key concept: the predicate. A predicate is simply a function that takes an item as input and returns a boolean (true or false) based on some condition.

You've already been using them with filter()! For example:

// The predicate here is the arrow function: `product => product.price > 100`
const expensiveProducts = products.filter(product => product.price > 100); 

The methods find() and findIndex() also rely on predicate functions to "test" each element in an array.

To solidify this concept, watch the first minute of this video.

8 Methods to Find, Search and Filter JavaScript Arrays

The video '8 Methods to Find, Search and Filter JavaScript Arrays' by Joel Codes starts with an excellent, concise explanation of what a predicate is. This will set the foundation for the next methods we'll cover.

Watch from the beginning until 01:13 to understand the concept of a predicate function.


2. find(): Retrieving an Element by Condition

The find() method is your go-to tool when you need to search an array for the first element that matches a complex condition (i.e., a predicate). This is especially powerful when working with arrays of objects.

A perfect use case, directly related to your e-commerce project goal, is finding a specific product in your catalog based on its ID.

To see how this works, please read the following sections from an article on dev.to. It provides clear examples that are highly relevant to your goals.

Array.find() Method - DEV Community

This article, 'Array.find() Method', clearly explains the syntax and provides practical examples, including some for an e-commerce context.

Read the sections titled 'What is Find Method?' and 'Examples'. Pay special attention to the 'Find product by id' example, as it's a pattern you will use frequently when building applications.

Key takeaways from the reading:

  • find() iterates through the array and returns the value of the first element for which the predicate function returns true.
  • If no element satisfies the condition, find() returns undefined.
  • It does not modify the original array.

Here's the product ID example from the article, which is a perfect illustration:

let products = [
  { id: 1, name: "Wireless Mouse" /* ... */ },
  { id: 2, name: "Ergonomic Chair" /* ... */ },
  { id: 3, name: "Bluetooth Keyboard" /* ... */ },
];

function getProductById(id) {
  // Use find() with a predicate to check the product's id
  const product = products.find(product => product.id === id);

  if (product) {
    console.log(`Product found: ${product.name}`);
    return product;
  } else {
    console.log("Product not found");
    return undefined;
  }
}

getProductById(2); // Logs: "Product found: Ergonomic Chair"
getProductById(4); // Logs: "Product not found"

3. findIndex(): Locating an Element's Position

Sometimes, you don't need the item itself, but rather its position (index) in the array. This is useful when you plan to modify that item later, for example, updating an item's quantity in a shopping cart or removing it using methods like splice() (which we'll cover soon).

findIndex() works just like find(), using the same predicate function, but with one key difference in its return value.

Now, read the next small section from the same dev.to article.

Array.find() Method - DEV Community

This section introduces findIndex() and contrasts it directly with find().

Read the section titled 'findIndex()'. Notice how it returns a number (the index) or -1.

Key takeaways:

  • findIndex() returns the index of the first element that satisfies the predicate.
  • If no element is found, it returns -1.

So, if we wanted to find the position of the product with id: 2:

const productIndex = products.findIndex(product => product.id === 2);
console.log(productIndex); // Output: 1

const missingIndex = products.findIndex(product => product.id === 4);
console.log(missingIndex); // Output: -1

The -1 return value is conventional in programming for "not found" when an index is expected.


4. includes(): Simple Existence Check

What if you don't need the element or its index, but just want a quick true or false answer to the question: "Is this value in the array?" For this, includes() is the most direct and readable tool.

Unlike find() and findIndex(), includes() does not take a predicate function. Instead, you pass it the literal value you're searching for.

The MOST IMPORTANT Javascript Array methods to understand (I use these all the time)

This clip from the 'The MOST IMPORTANT Javascript Array methods' video by Web Dev Cody gives a great overview of includes() and points out an important limitation when working with objects.

Watch from 02:55 to 03:50. Pay attention to how it's used and the narrator's comment about how it works with objects.

Key takeaways:

  • includes(value) returns true if value is found in the array, otherwise false.
  • It's perfect for checking for the presence of primitive values (strings, numbers, booleans).
  • Important: When used with objects, includes() checks for reference equality, not structural equality. This means it only returns true if the array contains a reference to the exact same object in memory, not just an object with the same properties.
const userRoles = ['editor', 'viewer', 'commenter'];
console.log(userRoles.includes('editor')); // true
console.log(userRoles.includes('admin'));  // false

const user1 = { name: 'Alice' };
const user2 = { name: 'Bob' };
const userArray = [user1, user2];

console.log(userArray.includes(user1)); // true (it's the exact same object)
console.log(userArray.includes({ name: 'Alice' })); // false (this is a new object, even if it looks the same)

For checking if an object with certain properties exists, you should use find().


5. Choosing the Right Method

Let's summarize when to use each method:

When you need... Use... Example Returns...
The element itself based on a condition. find() users.find(u => u.id === 42) The element, or undefined
The index of an element based on a condition. findIndex() products.findIndex(p => p.sku === 'xyz-123') The index, or -1
A true/false check for a specific value. includes() allowedRoles.includes('admin') true or false

6. Practice Exercise

Let's apply these methods to a combined e-commerce scenario.

You have a shoppingCart array and a user object.

const shoppingCart = [
  { id: 1, name: 'Wireless Mouse', quantity: 1 },
  { id: 3, name: 'Bluetooth Keyboard', quantity: 1 },
];

const user = {
  username: 'test_user',
  roles: ['customer', 'viewer'],
};

Your Tasks:

  1. A customer wants to add another 'Wireless Mouse' (id: 1) to their cart. Before adding a new item, you should check if it's already there to update its quantity instead. Write a line of code using find() to get the existing cart item with id: 1. Store it in a variable called existingItem.
  2. You need to check if the user has 'admin' privileges before showing them a dashboard link. Use includes() on the user.roles array to check for this. Store the result in a variable called isAdmin.
  3. You want to find the position of the 'Bluetooth Keyboard' (id: 3) in the cart, perhaps to remove it later. Use findIndex() to get its index. Store it in a variable called keyboardIndex.

Try to complete these tasks, then check your work against the solution below.

Click to see the solution
const shoppingCart = [
  { id: 1, name: 'Wireless Mouse', quantity: 1 },
  { id: 3, name: 'Bluetooth Keyboard', quantity: 1 },
];

const user = {
  username: 'test_user',
  roles: ['customer', 'viewer'],
};

// Task 1 Solution:
const existingItem = shoppingCart.find(item => item.id === 1);
console.log(existingItem); // { id: 1, name: 'Wireless Mouse', quantity: 1 }

// Task 2 Solution:
const isAdmin = user.roles.includes('admin');
console.log(isAdmin); // false

// Task 3 Solution:
const keyboardIndex = shoppingCart.findIndex(item => item.id === 3);
console.log(keyboardIndex); // 1

Conclusion

Great work! You've now added three powerful and precise tools to your array manipulation toolkit.

Key Takeaways:

  • Use find() when you need the object or value that matches a condition.
  • Use findIndex() when you need the position of an element that matches a condition.
  • Use includes() for a simple true/false check for the existence of a primitive value.

These methods, combined with map, filter, and reduce, give you a robust, declarative way to handle most of the data manipulation tasks you'll face.

In our next lesson, we'll continue our exploration of array methods by looking at sort(). You'll learn how to sort simple arrays and, more importantly, how to provide a custom comparator function to sort arrays of objects by properties like price, date, or name.