Searching an array answers questions like: is this value in the list? Where is it? Which student scored over 90? Some methods search for an exact value; others take a function that describes what you are looking for.
const tags = ["js", "css", "html"];
tags.includes("css") // true
tags.includes("CSS") // false (case-sensitive)
tags.includes("php") // false
const rolls = [3, 6, 2, 6, 1];
rolls.indexOf(6) // 1 first match
rolls.lastIndexOf(6) // 3 last match
rolls.indexOf(5) // -1 not found
0, which is falsy. Never write if (arr.indexOf(x)). Compare with !== -1, or use includes when you only need yes or no.
indexOf and lastIndexOf accept a second argument: the index to start from. A negative start counts back from the end:
const fruits = ["Apple", "Orange", "Apple", "Mango"];
console.log(fruits.indexOf("Apple", 1)); // search from index 1 onward
console.log(fruits.indexOf("Apple", -2)); // search the last 2 only
console.log(fruits.lastIndexOf("Apple", 1)); // search backward from index 1
const data = [1, NaN, 3];
console.log(data.indexOf(NaN));
console.log(data.includes(NaN));
indexOf compares with ===, and NaN === NaN is false (JS Numbers). includes has a special rule for NaN.
When you are looking for "the first item that matches a condition" rather than an exact value, pass a function. It is called for each element until it returns true:
const scores = [72, 88, 95, 61, 99];
scores.find(s => s > 90) // 95 the first value over 90
scores.findIndex(s => s > 90) // 2 its position
scores.find(s => s > 100) // undefined nothing matched
scores.findIndex(s => s > 100) // -1
scores.find(s > 90), does not work. JavaScript tries to calculate s > 90 right away, before find even runs, and s does not exist yet: ReferenceError: s is not defined. The argument must be a function.
Like every array method that takes a function, find passes three things: the value, its index, and the whole array. You can also pass a named function instead of an arrow:
function isAdult(value, index, array) {
return value >= 18;
}
const ages = [4, 9, 16, 25, 29];
console.log(ages.find(isAdult));
console.log(ages.findIndex(isAdult));
Notice find(isAdult), not find(isAdult()). You are handing over the function for find to call, not calling it yourself.
scores.findLast(s => s > 90) // 99 last value over 90
scores.findLastIndex(s => s > 90) // 4
This is where find really earns its place. indexOf and includes cannot look inside objects, but a function can:
const students = [
{ id: 101, name: "Ava", grade: 10 },
{ id: 102, name: "Ben", grade: 11 },
{ id: 103, name: "Cal", grade: 10 }
];
const ben = students.find(s => s.name === "Ben");
console.log(ben.id);
const pos = students.findIndex(s => s.id === 103);
console.log(pos);
// Why indexOf fails here: it compares object identity, not contents
students.indexOf({ id: 101, name: "Ava", grade: 10 }) // -1
const ages = [16, 17, 19, 15];
ages.some(a => a >= 18) // true at least one adult
ages.every(a => a >= 18) // false not all adults
ages.every(a => a > 10) // true
Both stop early: some at the first match, every at the first failure.
const names = ["Ada", "Grace", "Alan"];
const query = "grace";
names.find(n => n.toLowerCase() === query.toLowerCase()) // "Grace"
| Question | Method | Not found |
|---|---|---|
| Is this exact value in it? | includes | false |
| Where is this exact value? | indexOf / lastIndexOf | -1 |
| First item matching a rule? | find / findLast | undefined |
| Position of that item? | findIndex / findLastIndex | -1 |
| Any / all match a rule? | some / every | false |
To get all matching items, not just the first, use filter (in Array Iterations).
What does this log?
const v = [1, NaN, 3];
console.log(v.indexOf(NaN), v.includes(NaN));
-1 true. indexOf uses ===, and NaN is never === to anything, even itself. includes handles NaN specially.What does ["a", "b", "a", "c"].indexOf("a", 1) return?
012-1"a" and finds the one at index 2.You need the first student object whose grade is 11. Which method?
indexOfincludesfindsomefind returns the matching element itself. indexOf and includes cannot look inside objects, and some only answers true or false.[4, 8, -2, 7, -9] and its positionevery to check that all quiz answers in an array are filled in (not empty strings)