sort
Order a copy of the list with a comparator you control.
sort takes a comparator (a, b) that returns a negative number when a should come first, a positive number when b should, and zero when they tie. a - b sorts numbers ascending, b - a descending. Strings use a.localeCompare(b).
Two things bite everyone. First, sort with no comparator converts everything to strings, so [10, 9, 1] sorts to [1, 10, 9]. Always pass a comparator for numbers. Second, sort mutates the array in place. Copy first with [...items].sort(...), or use toSorted, which returns a new array.
Multi-key ordering is one comparator with a fallback: byPercentDesc || byNameAsc. The || moves to the next key only when the first one returns zero, a tie.
Shape
const ordered = [...items].sort((a, b) => a.score - b.score);
const ordered = items.toSorted((a, b) => b.score - a.score); Patterns
-
[...scores].sort((a, b) => b - a)Numbers descending, copy first.
-
[...docs].sort((a, b) => a.title.localeCompare(b.title))Strings, properly.
-
[...docs].sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt))Dates: subtract them. Newest first.
-
[...students].sort((a, b) => b.percent - a.percent || a.name.localeCompare(b.name))Two keys.
-
[...attempts].sort(byScore).slice(0, 3)Top N is sort, then slice.
Pitfalls
- No comparator means string order.
[10, 9, 1].sort()is[1, 10, 9]. sortmutates. If the caller keeps using the original array, they now have a reordered one they did not ask for.- A comparator must return a number. Returning a boolean like
a > bis wrong, becausefalsebecomes 0 and means "tie".
Exercises
Write the function, run it against the hidden cases. Cmd or Ctrl + Enter runs, Tab indents, Esc then Tab leaves the editor. 0 / 5 solved.
1. Scores descending
Return the scores from highest to lowest. Do not mutate the input.
scoresDescending([70, 100, 85, 9])
→ [100, 85, 70, 9] 2. By title
Return the documents alphabetically by title, ignoring case. Do not mutate the input.
byTitle(
[
{ title: "Onboarding" },
{ title: "API guide" },
{ title: "Q3 notes" }
]
) → [
{ title: "API guide" },
{ title: "Onboarding" },
{ title: "Q3 notes" }
] 3. Newest first
Return the documents ordered by updatedAt (ISO strings), newest first. Do not mutate the input.
newestFirst(
[
{ id: 1, updatedAt: "2026-09-01T10:00:00Z" },
{ id: 2, updatedAt: "2026-09-20T10:00:00Z" },
{ id: 3, updatedAt: "2026-09-10T10:00:00Z" }
]
) → [
{ id: 2, updatedAt: "2026-09-20T10:00:00Z" },
{ id: 3, updatedAt: "2026-09-10T10:00:00Z" },
{ id: 1, updatedAt: "2026-09-01T10:00:00Z" }
] 4. Rank students
Return the students ordered by percent descending, then by name ascending for ties. Do not mutate the input.
rankStudents(
[
{ name: "Cy", percent: 90 },
{ name: "Ana", percent: 100 },
{ name: "Bo", percent: 90 }
]
) → [
{ name: "Ana", percent: 100 },
{ name: "Bo", percent: 90 },
{ name: "Cy", percent: 90 }
] 5. Top N attempts
Return the n attempts with the highest percent, highest first. When two attempts tie on percent, the earlier submittedAt (an ISO string) ranks higher. If there are fewer than n attempts, return them all. Do not mutate the input.
topAttempts(
[
{ id: "c", percent: 75, submittedAt: "2026-09-01T10:00:00Z" },
{ id: "a", percent: 75, submittedAt: "2026-09-02T10:00:00Z" },
{ id: "b", percent: 100, submittedAt: "2026-09-03T10:00:00Z" },
{ id: "d", percent: 50, submittedAt: "2026-09-04T10:00:00Z" }
],
2
) → [
{ id: "b", percent: 100, submittedAt: "2026-09-03T10:00:00Z" },
{ id: "c", percent: 75, submittedAt: "2026-09-01T10:00:00Z" }
]