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 returnstrue.- If no element satisfies the condition,
find()returnsundefined. - 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)returnstrueifvalueis found in the array, otherwisefalse.- 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 returnstrueif 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:
- 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 usingfind()to get the existing cart item withid: 1. Store it in a variable calledexistingItem. - You need to check if the user has
'admin'privileges before showing them a dashboard link. Useincludes()on theuser.rolesarray to check for this. Store the result in a variable calledisAdmin. - You want to find the position of the 'Bluetooth Keyboard' (
id: 3) in the cart, perhaps to remove it later. UsefindIndex()to get its index. Store it in a variable calledkeyboardIndex.
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 simpletrue/falsecheck 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.