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.

5 min read

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:

javascriptjavascript
const numbers = [5, 12, 8, 130, 44];
 
const firstLarge = numbers.find(n => n > 10);
 
console.log(firstLarge); // 12

The 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:

javascriptjavascript
const numbers = [1, 2, 3];
 
const result = numbers.find(n => n > 100);
 
console.log(result); // undefined

Finding 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:

javascriptjavascript
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:

javascriptjavascript
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:

javascriptjavascript
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:

javascriptjavascript
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:

javascriptjavascript
const index = fruits.findIndex(fruit => fruit.startsWith("z"));
 
console.log(index); // -1

This 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:

javascriptjavascript
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:

javascriptjavascript
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:

javascriptjavascript
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:

javascriptjavascript
if (removeIndex !== -1) {
  todos2.splice(removeIndex, 1);
}
 
console.log(todos2.length); // 2

For more on splice(), see JS Array slice vs splice.

find() vs filter() vs some()

These three methods are easy to confuse:

MethodReturnsStops early?Use case
find(fn)First matching element or undefinedYes"Get me the element with id 5"
filter(fn)Array of all matching elementsNo"Show all products on sale"
some(fn)true or falseYes"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()

MethodMatches byReturns no matchUse 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.

javascriptjavascript
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:

javascriptjavascript
const users = [{ id: 1, name: "Alice" }];
 
const user = users.find(u => u.id === 999);
console.log(user.name); // TypeError: Cannot read properties of undefined

Checking the result first avoids the crash and lets you handle the missing case explicitly, showing a fallback message instead of breaking the page:

javascriptjavascript
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:

javascriptjavascript
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:

javascriptjavascript
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:

javascriptjavascript
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:

javascriptjavascript
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

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.
RunePowered by Rune AI

Frequently Asked Questions

What does find() return if no element matches?

find() returns undefined when no element passes the test. It does not throw an error or return null.

What does findIndex() return if no element matches?

findIndex() returns -1 when no element passes the test. This is consistent with indexOf().

How is find() different from filter()?

find() returns the first matching element as a single value. filter() returns all matching elements in a new array. Use find() when you expect one match. Use filter() when you need all matches.

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.