JavaScript Array Find and findIndex Methods Guide
find() returns the first element that matches a condition. findIndex() returns its index. Learn how to search arrays beyond indexOf with clear examples.
find() and findIndex() search an array for the first element that satisfies a condition you provide. Unlike indexOf() and includes(), which only match by exact value, these methods let you search using any logic.
- find() returns the first matching element (or undefined).
- findIndex() returns the index of the first matching element (or -1).
Both stop searching as soon as they find a match.
find() -- Get the First Matching Element
find() passes each element to a callback and stops as soon as one makes the callback return true, returning that element directly. Here is the smallest possible example, searching a plain array of numbers:
const numbers = [5, 12, 8, 130, 44];
const firstLarge = numbers.find(n => n > 10);
console.log(firstLarge); // 12The search stops at 12. The remaining elements 8, 130, and 44 are never checked, which is what makes find() efficient on large arrays.
If no element matches, find() returns undefined instead of throwing an error or returning null:
const numbers = [1, 2, 3];
const result = numbers.find(n => n > 100);
console.log(result); // undefinedFinding Objects by Property
The most common use of find() is locating an object by a property, such as looking up a specific user by their id:
const users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
{ id: 3, name: "Carol" }
];
const user = users.find(u => u.id === 2);
console.log(user); // { id: 2, name: "Bob" }This is cleaner than filter()[0], which finds the same object but builds an unnecessary array along the way just to immediately throw it away:
const userViaFilter = users.filter(u => u.id === 2)[0];
console.log(userViaFilter); // { id: 2, name: "Bob" }find() produces the identical result while stopping at the very first match instead of scanning the whole array and collecting matches it will never use:
const userViaFind = users.find(u => u.id === 2);
console.log(userViaFind); // { id: 2, name: "Bob" }findIndex() -- Get the Position of the First Match
findIndex() works like find() but returns the index instead of the element, which is useful when you need to update or remove the matching item afterward:
const fruits = ["apple", "banana", "cherry", "date"];
const index = fruits.findIndex(fruit => fruit.startsWith("c"));
console.log(index); // 2
console.log(fruits[index]); // "cherry"When no element matches, findIndex() returns -1 instead of throwing an error, so you can safely check the result before using it:
const index = fruits.findIndex(fruit => fruit.startsWith("z"));
console.log(index); // -1This is consistent with indexOf(), which also returns -1 for no match.
Practical findIndex() Use Cases
Replacing an element at a known condition. Once you have the index, you can update that one item in place without touching the rest of the array:
const todos = [
{ id: 1, task: "Buy milk", done: false },
{ id: 2, task: "Walk dog", done: false },
{ id: 3, task: "Read book", done: false }
];
const index = todos.findIndex(t => t.id === 2);Guarding with index !== -1 before writing to todos[index] avoids accidentally modifying the wrong slot, or crashing the program entirely, when nothing matches the condition:
if (index !== -1) {
todos[index].done = true;
}
console.log(todos[1]); // { id: 2, task: "Walk dog", done: true }Removing an element by condition. The same lookup pattern works with splice() to remove the matching item instead of updating it:
const todos2 = [
{ id: 1, task: "Buy milk", done: false },
{ id: 2, task: "Walk dog", done: false },
{ id: 3, task: "Read book", done: false }
];
const removeIndex = todos2.findIndex(t => t.id === 2);The same -1 guard applies before removing, since splicing at index -1 would delete the last element instead of doing nothing, which is rarely the intended behavior:
if (removeIndex !== -1) {
todos2.splice(removeIndex, 1);
}
console.log(todos2.length); // 2For more on splice(), see JS Array slice vs splice.
find() vs filter() vs some()
These three methods are easy to confuse:
| Method | Returns | Stops early? | Use case |
|---|---|---|---|
find(fn) | First matching element or undefined | Yes | "Get me the element with id 5" |
filter(fn) | Array of all matching elements | No | "Show all products on sale" |
some(fn) | true or false | Yes | "Is any product on sale?" |
Use find() when you expect and want exactly one result. Use filter() when you want all matching results. Use some() when you only need a yes/no answer.
findIndex() vs indexOf()
| Method | Matches by | Returns no match | Use case |
|---|---|---|---|
indexOf(val) | Strict equality (===) | -1 | "Where is the number 5?" |
findIndex(fn) | Callback condition | -1 | "Where is the first number > 5?" |
Use indexOf() for simple value lookups. Use findIndex() when you need a condition more complex than strict equality.
const numbers = [1, 5, 10, 15];
// indexOf: find by exact value
console.log(numbers.indexOf(10)); // 2
// findIndex: find by condition
console.log(numbers.findIndex(n => n > 7)); // 2 (10 is the first > 7)Common Mistakes
Not checking for undefined with find(). Assuming a match always exists and reading a property straight off the result crashes the moment nothing matches:
const users = [{ id: 1, name: "Alice" }];
const user = users.find(u => u.id === 999);
console.log(user.name); // TypeError: Cannot read properties of undefinedChecking the result first avoids the crash and lets you handle the missing case explicitly, showing a fallback message instead of breaking the page:
if (user) {
console.log(user.name);
} else {
console.log("User not found");
}Always check that find() returned something before accessing properties on the result.
Using filter()[0] instead of find(). Both return the same element here, but filter() still builds and discards an array behind the scenes:
const products = [
{ name: "Laptop", price: 999 },
{ name: "Mouse", price: 29 },
{ name: "Monitor", price: 299 }
];
const cheapViaFilter = products.filter(p => p.price < 50)[0];
console.log(cheapViaFilter); // { name: "Mouse", price: 29 }Using find() instead returns the same result without ever creating that intermediate array, which matters more as the source array grows larger:
const cheapViaFind = products.find(p => p.price < 50);
console.log(cheapViaFind); // { name: "Mouse", price: 29 }filter() processes every element even though you only need the first one. find() short-circuits.
Confusing findIndex() return value of -1 as truthy. In JavaScript, -1 is truthy, so checking the index directly instead of comparing it to -1 is a common bug:
const items = [{ id: 1 }, { id: 2 }];
const index = items.findIndex(item => item.id === 999);
if (index) {
console.log("Found at", index); // Wrong: this runs even when index is -1
}Comparing explicitly against -1 fixes it, since that is the only value findIndex() ever uses to signal that no element matched the condition:
if (index !== -1) {
console.log("Found at", index);
} else {
console.log("Not found");
}In JavaScript, -1 is truthy. The only falsy numbers are 0 and NaN. Always compare findIndex() results against -1 explicitly.
Now that you can find elements, learn how to order them with sort.
Rune AI
Key Insights
- find() returns the first element that passes the test callback, or undefined if none do.
- findIndex() returns the index of the first match, or -1 if no match is found.
- Both methods stop iterating as soon as they find a match (short-circuit).
- Use find() instead of filter()[0] when you expect a single result.
- Use findIndex() instead of indexOf() when you need to match by a condition, not a value.
Frequently Asked Questions
What does find() return if no element matches?
What does findIndex() return if no element matches?
How is find() different from filter()?
Conclusion
find() and findIndex() are the methods you use when you need the first element (or its position) that satisfies a condition. They stop searching as soon as they find a match, making them efficient. Use find() for retrieving objects by ID, checking existence with better semantics than filter(), and locating specific elements by any condition you can express as a function.
More in this topic
JavaScript While Loop Explained: A Complete Guide
A while loop repeats code as long as a condition stays true. Learn the syntax, see practical examples, and understand when a while loop is the right choice over a for loop.
JavaScript Loops Tutorial: for, while, do while
Loops let JavaScript repeat code without writing it twice. Learn the three core loop types, what each one does, and when to choose one over another.
How to Loop Through Arrays Using JS for Loops Guide
Looping through arrays is the most practical use of JavaScript for loops. Learn how to access each element by index, avoid off-by-one errors, and choose between for, for...of, and forEach.