Episode 1 — Fundamentals / 1.22 — Array Methods

1.22 — Array Methods: Quick Revision

Compact cheat sheet. Print-friendly.

How to use this material (instructions)

  1. Skim before labs or interviews.
  2. Drill gaps — reopen README.md1.22.a1.22.j.
  3. Practice1.22-Exercise-Questions.md.
  4. Polish answers1.22-Interview-Questions.md.

Method overview table

MethodReturnsMutates?Purpose
map(fn)New array (same length)NoTransform each element
filter(fn)New array (subset)NoSelect elements by test
reduce(fn, init)Single value (any type)NoAccumulate / aggregate
forEach(fn)undefinedNoSide effects only
some(fn)booleanNoAny element passes?
every(fn)booleanNoAll elements pass?
find(fn)Element or undefinedNoFirst match
findIndex(fn)Index or -1NoIndex of first match
slice(s, e)New array (portion)NoExtract without mutating
splice(s, d, ...i)Array of deleted itemsYesInsert / remove / replace
sort(fn)Same array (sorted)YesOrder elements
reverse()Same array (reversed)YesReverse order
flat(depth)New array (flattened)NoFlatten nesting
flatMap(fn)New array (map+flat 1)NoMap and flatten one level
concat(...arrs)New array (merged)NoJoin arrays
includes(val)booleanNoContains value?
indexOf(val)Index or -1NoFirst index of value

ES2023 non-mutating counterparts

MutatingNon-mutating
sort(fn)toSorted(fn)
reverse()toReversed()
splice(s, d, ...i)toSpliced(s, d, ...i)
arr[i] = valarr.with(i, val)

Callback signatures

map:      (element, index, array) => newValue
filter:   (element, index, array) => boolean
reduce:   (accumulator, current, index, array) => newAccumulator
forEach:  (element, index, array) => void
some:     (element, index, array) => boolean
every:    (element, index, array) => boolean
find:     (element, index, array) => boolean
sort:     (a, b) => number  (negative = a first, 0 = equal, positive = b first)

Key patterns

Filter then map (narrow then transform)

arr.filter(x => x.active).map(x => x.name)

Frequency counter

arr.reduce((acc, val) => { acc[val] = (acc[val] || 0) + 1; return acc; }, {})

Group by key

arr.reduce((g, item) => { (g[item.key] ??= []).push(item); return g; }, {})

Sum

arr.reduce((sum, n) => sum + n, 0)

Remove falsy values

arr.filter(Boolean)

Unique values

[...new Set(arr)]

Immutable remove at index

[...arr.slice(0, i), ...arr.slice(i + 1)]

Immutable insert at index

[...arr.slice(0, i), newItem, ...arr.slice(i)]

Sort numbers (not lexicographic)

arr.sort((a, b) => a - b)          // ascending
arr.sort((a, b) => b - a)          // descending

Sort strings properly

arr.sort((a, b) => a.localeCompare(b))

Flatten all levels

arr.flat(Infinity)

Gotchas to remember

GotchaWhat happensFix
map without returnArray of undefinedAdd return or use concise arrow
Returning object in arrown => { key: n }undefinedWrap: n => ({ key: n })
forEach return valueAlways undefinedUse map if you need results
await in forEachFires concurrently, does not waitUse for...of or Promise.all
reduce no initial valueCrashes on empty arrayAlways pass second argument
reduce no returnAccumulator becomes undefinedAlways return acc
sort() defaultLexicographic: [1,10,2]Pass compare function
sort() mutatesOriginal array changedCopy first: [...arr].sort()
splice() mutatesOriginal array changedUse slice + spread for immutable
slice vs splice namesEasy to confuseslice = copy, splice = cut/place
filter(Boolean) with 0Removes 0 (it is falsy)Use explicit check if 0 is valid
some([]) / every([])false / trueVacuous truth — intentional

Decision flowchart

Need new array of same length?     → map
Need subset of elements?           → filter
Need single value from array?      → reduce
Just doing something per element?  → forEach
Any element matches?               → some
All elements match?                → every
Find first match?                  → find / findIndex
Extract portion (no mutate)?       → slice
Insert/remove in place?            → splice (or toSpliced for immutable)
Sort?                              → toSorted (or [...arr].sort())
Flatten nesting?                   → flat / flatMap

Chaining order

source data
  .filter(...)     ← narrow the set (fewer elements = less work downstream)
  .map(...)        ← transform each element
  .sort(...)       ← order the results
  .slice(0, n)     ← take top N (pagination)
  .reduce(...)     ← aggregate into final value

Empty array behavior

MethodEmpty array result
[].map(fn)[]
[].filter(fn)[]
[].reduce(fn, init)init
[].reduce(fn)TypeError
[].forEach(fn)undefined (callback never runs)
[].some(fn)false
[].every(fn)true
[].find(fn)undefined
[].sort()[]
[].flat()[]

Master workflow

  1. Identify — Do you need to transform, filter, accumulate, or just iterate?
  2. Pick method — Use the decision flowchart above.
  3. Chain — Compose methods in a pipeline: filter → map → reduce.
  4. Immutability — Prefer non-mutating methods. Copy before sort/splice.
  5. Optimize later — Only collapse chains into a single loop if profiling shows a bottleneck.

End of 1.22 quick revision.