Skip to content

Intermediate · JavaScript in depth · topic 32 of 64 · 35 min

More array power

Explanation

Beyond map, filter and reduce, arrays have tools to ask yes or no questions (some, every), find positions (findIndex, findLast), sort lists of objects, flatten nested lists and group items. You will also learn which methods change the original array and which give you a new one, and how destructuring, rest and spread make array code shorter.

Yes or no questions: some and every

javascript
const marks = [72, 45, 88, 30];
marks.some((m) => m < 35);   // true  (at least one failed)
marks.every((m) => m >= 35); // false (not everyone passed)
[].every((m) => m > 100);    // true  (an empty list passes every test!)
Both stop early as soon as they know the answer
Think of it like this: some is like a teacher asking "Has anyone finished?": one raised hand is enough for yes. every is like checking that every student brought the permission slip for a school trip: one missing slip makes the answer no.

Finding positions

javascript
const orders = [
  { id: 'A1', status: 'paid' },
  { id: 'A2', status: 'pending' },
  { id: 'A3', status: 'pending' },
];
orders.findIndex((o) => o.status === 'pending');  // 1
orders.findLast((o) => o.status === 'pending');   // { id: 'A3', status: 'pending' }
orders.findLastIndex((o) => o.id === 'Z9');       // -1 (not found)
These take a test function. includes and indexOf (from JavaScript basics) only compare with ===, so they cannot search objects by a key

Sorting lists of objects

javascript
const students = [
  { name: 'Zoya', marks: 81 },
  { name: 'arjun', marks: 92 },
  { name: 'Meera', marks: 81 },
];
// by a number, high to low
const byMarks = students.toSorted((a, b) => b.marks - a.marks);
// by text, A to Z (localeCompare handles capitals sensibly)
const byName = students.toSorted((a, b) => a.name.localeCompare(b.name));
// by marks, and by name when the marks are equal
const ranked = students.toSorted(
  (a, b) => b.marks - a.marks || a.name.localeCompare(b.name)
);
toSorted returns a sorted copy and leaves students unchanged
Tip: The || trick sorts by two things. When the marks are equal, b.marks - a.marks is 0, which is falsy, so the name comparison after || decides the order.

Changes the array, or gives a new one?

Changes the original (mutates)Gives a new array instead
sort(fn)toSorted(fn)
reverse()toReversed()
splice(i, n)toSpliced(i, n)
list[i] = xlist.with(i, x)
push(x) / unshift(x)[...list, x] / [x, ...list]
pop() / shift()list.slice(0, -1) / list.slice(1)

map, filter, find, some, every, slice, concat, flat and join never change the original. toSorted, toReversed, toSpliced and with were added in 2023 and work in all current browsers. In front-end code, and especially in React, prefer the non-mutating forms, because other parts of the page may still be using the old array.

Flattening and building arrays

javascript
[[1, 2], [3], [4, 5]].flat();       // [1, 2, 3, 4, 5]
[1, [2, [3, [4]]]].flat(Infinity);  // [1, 2, 3, 4]

const orders = [
  { id: 'A1', items: ['rice', 'dal'] },
  { id: 'A2', items: ['oil'] },
];
orders.flatMap((o) => o.items);     // ['rice', 'dal', 'oil']

Array.from('UPI');                          // ['U', 'P', 'I']
Array.from({ length: 5 }, (_, i) => i + 1); // [1, 2, 3, 4, 5]
Array.from(new Set([3, 1, 3, 2, 1]));       // [3, 1, 2]  duplicates removed
flatMap = map then flat by one level; Array.from makes a real array from anything list-like

Destructuring, rest and spread

javascript
const [first, second] = ['Gold', 'Silver', 'Bronze'];     // 'Gold', 'Silver'
const [winner, ...others] = ['Gold', 'Silver', 'Bronze']; // others = ['Silver', 'Bronze']

let a = 1;
let b = 2;
[a, b] = [b, a];               // swap: now a is 2 and b is 1

const all = [...[1, 2], ...[3, 4]]; // [1, 2, 3, 4]

function sum(...numbers) {     // rest parameter: any number of arguments
  return numbers.reduce((s, n) => s + n, 0);
}
sum(10, 20, 30);               // 60
Math.max(...[4, 9, 2]);        // 9  spread turns an array into arguments
Three dots collect (rest) or spread out (spread), depending on where they stand
Tip: In a parameter list or on the left of =, the three dots collect the remaining items into an array (rest). In a function call or inside [ ], they spread the items out (spread).

Grouping and chaining

javascript
const orders = [
  { id: 'A1', city: 'Pune', amount: 300 },
  { id: 'A2', city: 'Delhi', amount: 150 },
  { id: 'A3', city: 'Pune', amount: 220 },
];
const byCity = orders.reduce((groups, order) => {
  const key = order.city;
  if (!groups[key]) groups[key] = [];
  groups[key].push(order);
  return groups;
}, {});
// { Pune: [A1, A3], Delhi: [A2] }

// The modern shortcut (added in 2024, works in current browsers):
const same = Object.groupBy(orders, (o) => o.city);
reduce can build an object as well as a number
javascript
const topOrders = orders
  .filter((o) => o.amount > 200)
  .toSorted((a, b) => b.amount - a.amount)
  .map((o) => `${o.id}: Rs ${o.amount}`);
// ['A1: Rs 300', 'A3: Rs 220']
Chaining: each method works on the result of the one before. Put one method per line so it reads like steps
Careful: sort() and reverse() change the array in place and also return it. So const sorted = list.sort() gives you two names for one changed list, and the original order is gone. Use toSorted() or [...list].sort() instead.

Watch the lesson

More array power · 1/7

some = anyone? every = everyone?

some asks: does at least one item pass? every asks: do all items pass?

Prefer a video by a teacher? Find free videos on “javascript array methods some every flatMap toSorted destructuring spread rest” on YouTube ↗

In real life: Exam results on a school portal

A school portal gets every student's marks from the server. every checks if the whole class passed, some flags if anyone needs a re-test, toSorted ranks students by marks and then by name, reduce groups them by section (A, B, C), and flatMap collects all subject marks to work out a class average. The original list stays unchanged, so the "Sort by roll number" button still works.

Practice (0/3 done)

Task 1 · Code · Javascript

Write two functions. allPassed(marks) returns true if every mark is 35 or more. hasDistinction(marks) returns true if at least one mark is 75 or more. Example: allPassed([40, 72, 35]) is true and hasDistinction([40, 72, 35]) is false. Use every and some.

Task 2 · Code · Javascript

Write a function rankStudents(students) that returns a NEW array sorted by marks from high to low. Students with equal marks are sorted by name, A to Z, using localeCompare. Do not change the original array. Example: [{ name: "Zoya", marks: 81 }, { name: "Arjun", marks: 92 }, { name: "Meera", marks: 81 }] gives Arjun, Meera, Zoya.

Task 3 · Code · Javascript

Write a function totalByCity(orders) that uses reduce to return an object with the total amount for each city. Example: [{ city: "Pune", amount: 300 }, { city: "Delhi", amount: 150 }, { city: "Pune", amount: 220 }] gives { Pune: 520, Delhi: 150 }. An empty list gives {}.

Quick quiz

Question 1

1.What does [2, 4, 7].every((n) => n % 2 === 0) return?

Question 2

2.Which method does NOT change the original array?

Question 3

3.const [a, ...rest] = [1, 2, 3]; What is rest?

Question 4

4.What does [['a'], ['b', 'c']].flat() return?

Question 5

5.names holds 'Zoya', 'arjun' and 'Meera'. Which sorts them A to Z the way a person would?

Read more (free)

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

← Previous: Strings in depth