Essential Array Methods
Reviewed & published by Brayan K
Beyond map and filter, JavaScript arrays ship with a toolbox of built-in methods — find, some, every, flat, sort, and the immutable toSorted — that let you search, test, flatten, and reorder data without writing loops.
Part of the free JavaScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Knowing which method fits a task is the difference between five lines of loop and one expressive line.
What You'll Learn in This Lesson
- Search with find & findIndex
- Test with some, every & includes
- Flatten nested arrays with flat/flatMap
- Read from the end with at()
- Sort numbers with a compare function
- Sort immutably with toSorted/toReversed
📚 Prerequisites: You should know arrays and callback functions / arrow functions. Most of these methods take a small callback that runs once per element.
🧰 Real-World Analogy: Array methods are like kitchen tools:
- • find is tongs — grab the first item that matches
- • some/every are inspectors — "is any spoiled?" / "are all ripe?"
- • flat empties nested bags onto one tray
- • toSorted is a careful chef — arranges a fresh plate without disturbing the original
1️⃣ Searching & Testing: find, some, every, includes
These four answer questions about an array. find returns the first matching element (or undefined); findIndex returns its position (or -1). some returns true if at least one element passes; every returns true only if all do. includes checks for an exact value — handy for primitives.
find vs filter: reach for find when you want one result. filter always returns an array, so checking it requires .length.
const products = [
{ name: "Pen", price: 2 },
{ name: "Mug", price: 9 },
{ name: "Bag", price: 25 },
];
console.log(products.find(p => p.price > 5)?.name); // ✅ Expected output: Mug
console.log(products.findIndex(p => p.price > 5)); // ✅ Expected output: 1
console.log(products.some(p => p.price > 20)); // ✅ Expected output: true
console.log(products.every(p => p.price > 0)); // ✅ Expected output: true
const tags = ["js", "css", "html"];
console.log(tags.includes("css")); // ✅ Expected output: true2️⃣ Flattening & Indexing: flat, flatMap, at, fill
flat() collapses nested arrays — pass a depth (or Infinity) to go deeper. flatMap() maps then flattens one level in a single pass, perfect for expanding each item. at() reads by index and accepts negatives, so arr.at(-1) is the last element. fill() overwrites a range with one value.
at(-1) is the modern "last element": cleaner than arr[arr.length - 1] and it works on strings too.
const nested = [1, [2, [3, [4]]]];
console.log(nested.flat(2)); // ✅ Expected output: [ 1, 2, 3, [ 4 ] ]
console.log(nested.flat(Infinity)); // ✅ Expected output: [ 1, 2, 3, 4 ]
const sentences = ["hello world", "good day"];
console.log(sentences.flatMap(s => s.split(" ")));
// ✅ Expected output: [ 'hello', 'world', 'good', 'day' ]
const scores = [10, 20, 30];
console.log(scores.at(-1)); // ✅ Expected output: 30
console.log([0, 0, 0, 0].fill(7, 1, 3)); // ✅ Expected output: [ 0, 7, 7, 0 ]3️⃣ Sorting: compare functions & immutable toSorted/toReversed
sort() compares elements as strings by default, which mangles numbers. Pass a compare function: return a negative number to put a first, positive to put b first. (a, b) => a - b sorts ascending. The catch: sort() and reverse() mutate the original. The ES2023 toSorted() and toReversed() return a fresh array and leave the source untouched.
Prefer the immutable versions (toSorted, toReversed, toSpliced, with) when the data is shared — they prevent surprise mutations.
const nums = [10, 2, 30, 4];
console.log([...nums].sort()); // ✅ Expected output: [ 10, 2, 30, 4 ]
console.log(nums.toSorted((a, b) => a - b)); // ✅ Expected output: [ 2, 4, 10, 30 ]
console.log(nums.toSorted((a, b) => b - a)); // ✅ Expected output: [ 30, 10, 4, 2 ]
// Original is untouched by the immutable methods
console.log(nums); // ✅ Expected output: [ 10, 2, 30, 4 ]
console.log(["c", "a", "b"].toReversed()); // ✅ Expected output: [ 'b', 'a', 'c' ]🎯 Your Turn — Find the First Match
Use the right method to get the first number greater than 100.
const readings = [12, 45, 130, 8, 200];
// 👉 replace ___ with the method that returns the FIRST match
const firstBig = readings.___(n => n > 100);
console.log(firstBig);
// ✅ Expected output: 130🧠 Quick Recall
Predict the output before revealing the answer.
[ 1, 22, 3 ] — default sort compares strings, so "22" comes before "3".
6 — at(-2) counts back two from the end.
true — at least one element (3) passes the test.
Common Errors & Fixes
- 1️⃣ Sorting numbers without a compare function
- 2️⃣ Forgetting sort() mutates the original
- 3️⃣ Using includes with objects
- 4️⃣ Assuming find returns an array
🎯 Mini Challenge — Top Scorer Report
Sort players by score (highest first) without mutating the input, then report the top name.
const players = [
{ name: "Ana", score: 42 },
{ name: "Bo", score: 91 },
{ name: "Cy", score: 67 },
];
// 👉 sort a COPY by score descending, then read the first name
const ranked = players.toSorted((a, b) => b.score - a.score);
console.log(ranked.at(0).name); // ✅ Expected output: Bo
console.log(ranked.at(-1).name); // ✅ Expected output: Ana
// original order preserved
console.log(players[0].name); // ✅ Expected output: AnaQuick Reference
| Method | Returns |
|---|---|
| find | first match or undefined |
| some / every | boolean |
| flat / flatMap | flattened array |
| at | element (negatives allowed) |
| toSorted / toReversed | new array (no mutation) |
📚 Keep Learning
- MDN: Array reference
- MDN: Array.prototype.toSorted()
- MDN: Array.prototype.flatMap()
🎉 Lesson Complete — Essential Array Methods!
- ✅ find/findIndex locate; some/every/includes test
- ✅ flat/flatMap collapse nested arrays
- ✅ at(-1) is the clean way to read from the end
- ✅ sort needs a compare function for numbers
- ✅ toSorted/toReversed return new arrays without mutating
Practice quiz
What does arr.find(fn) return when no element passes the test?
- null
- -1
- undefined
- an empty array
Answer: undefined. find returns the first matching element, or undefined when nothing matches (findIndex returns -1).
What does [1, [2, [3, [4]]]].flat(2) produce?
- [1, 2, 3, 4]
- [1, 2, 3, [4]]
- [1, 2, [3, [4]]]
- [1, [2, [3, [4]]]]
Answer: [1, 2, 3, [4]]. flat(2) flattens two levels deep, leaving the [4] still nested one level down.
What is the value of [10, 20, 30].at(-1)?
- 10
- 20
- 30
- undefined
Answer: 30. at() accepts negative indices, so at(-1) reads the last element, 30.
What does [3, 22, 1].sort() log?
- [1, 3, 22]
- [1, 22, 3]
- [22, 3, 1]
- [3, 22, 1]
Answer: [1, 22, 3]. Default sort compares elements as strings, so '22' comes before '3'.
Which compare function sorts numbers in ascending order?
- (a, b) => b - a
- (a, b) => a - b
- (a, b) => a > b
- (a, b) => a
Answer: (a, b) => a - b. (a, b) => a - b returns negative when a should come first, giving ascending order.
How do toSorted() and toReversed() differ from sort() and reverse()?
- They are faster
- They mutate the original array
- They return a new array without mutating the original
- They only work on numbers
Answer: They return a new array without mutating the original. The ES2023 immutable versions return a fresh array and leave the source untouched.
What does [4, 9, 12].some(n => n % 2 === 0) return?
- true
- false
- [4, 12]
- 1
Answer: true. some returns true if at least one element passes; 4 and 12 are even.
What does ["a b", "c"].flatMap(s => s.split(" ")) produce?
- [["a", "b"], ["c"]]
- ["a b", "c"]
- ["a", "b", "c"]
- ["a", "b c"]
Answer: ["a", "b", "c"]. flatMap maps each string to an array of words, then flattens one level into a single array.
Why does users.includes({ id: 1 }) return false even if such an object exists?
- includes does not work on arrays of objects
- includes compares by reference, and the literal is a different object
- includes only checks the first element
- You must pass a callback
Answer: includes compares by reference, and the literal is a different object. includes uses value equality; two different object references are never equal, so use some(u => u.id === 1).
What does [10, 2, 1].sort((a, b) => a - b) return?
- [1, 10, 2]
- [10, 2, 1]
- [1, 2, 10]
- [2, 1, 10]
Answer: [1, 2, 10]. With a numeric compare function it sorts ascending: [1, 2, 10].
Continue this course
- Previous: Optional Chaining & Nullish Coalescing
- Next: Object Methods (keys, entries, assign, freeze) — Iterate, copy, merge and lock objects with the built-in Object methods
- Quick reference: JavaScript cheat sheet
- From the blog: Array Methods in JavaScript You Must Know
Frequently asked questions
What is the difference between find and filter?
find returns the FIRST element that matches your test, or undefined if none match. filter returns a NEW array of ALL matching elements (possibly empty). Use find when you want one item, filter when you want a subset.
Why does sort() sometimes produce a weird order?
By default sort converts elements to strings and compares them, so [10, 2, 1] becomes [1, 10, 2]. To sort numbers you must pass a compare function: arr.sort((a, b) => a - b). The compare returns a negative number, zero, or positive number to decide order.
What do toSorted and toReversed do that sort and reverse do not?
sort() and reverse() mutate the original array in place. The ES2023 methods toSorted() and toReversed() return a brand-new sorted/reversed array and leave the original untouched — much safer in code that shares data, like React state.
What is the point of flatMap?
flatMap maps each element to an array and then flattens the result one level — in a single pass. It is ideal for expanding each item into zero, one, or many items, such as splitting sentences into words or removing items by mapping them to an empty array.