Higher Order
Array higher-order methods: map, filter, reduce, find, some, every, join, forEach.
const nums: number[] = [1, 2, 3, 4, 5]
// ── map ───────────────────────────────────────────────────────────────────────
const doubled = nums.map(x => x * 2)
console.log(doubled[0]) // 2
console.log(doubled[4]) // 10
// ── filter ────────────────────────────────────────────────────────────────────
const evens = nums.filter(x => x % 2 === 0)
console.log(evens.length) // 2
console.log(evens[0]) // 2
console.log(evens[1]) // 4
// ── reduce ────────────────────────────────────────────────────────────────────
const sum = nums.reduce((acc, n) => acc + n, 0)
console.log(sum) // 15
const product = nums.reduce((acc, n) => acc * n, 1)
console.log(product) // 120
// The initial value is optional — the array's own first element seeds the
// accumulator, and the fold starts from the second element.
const sumNoInitial = nums.reduce((acc, n) => acc + n)
console.log(sumNoInitial) // 15 (same as sum above)
// With a single element and no initial value, the callback never runs —
// the seeded first element is the whole result.
const single: number[] = [42]
console.log(single.reduce((acc, n) => acc + n)) // 42
// An empty array with no initial value throws, matching real JS.
const empty: number[] = []
try {
empty.reduce((acc, n) => acc + n)
} catch (e) {
console.log(e.message) // Reduce of empty array with no initial value
}
// ── find ──────────────────────────────────────────────────────────────────────
const first3 = nums.find(x => x > 3)
console.log(first3) // 4
// ── some ──────────────────────────────────────────────────────────────────────
const hasEven = nums.some(x => x % 2 === 0)
console.log(hasEven) // 1
const allPositive = nums.every(x => x > 0)
console.log(allPositive) // 1
const allEven = nums.every(x => x % 2 === 0)
console.log(allEven) // 0
// ── join ──────────────────────────────────────────────────────────────────────
const words: string[] = ['hello', 'world', 'typego']
const joined = words.join(', ')
console.log(joined) // hello, world, typego
const nums2: number[] = [1, 2, 3]
const csv = nums2.join(',')
console.log(csv) // 1,2,3
// ── forEach ───────────────────────────────────────────────────────────────────
nums2.forEach(x => {
console.log(x * 10) // 10, 20, 30
})
nums2.forEach((x, i) => {
console.log(`${i}: ${x}`) // 0: 1, 1: 2, 2: 3
})
let total = 0
nums2.forEach(x => {
total += x
})
console.log(total) // 6
// ── Unannotated callback parameters over a non-numeric (string[]) array ───────
// Every HOF method propagates the array's element type as a hint to an
// unannotated callback parameter — without this, `n` below would silently
// default to `number`, and `n.length` would fail since a number has no
// `.length`. Also covers an expression-bodied callback whose only statement
// is a void-returning call like console.log (a common forEach shape).
const names: string[] = ['apple', 'bob', 'cat']
names.forEach(n => console.log(n)) // apple, bob, cat
const lengths = names.map(n => n.length)
console.log(lengths[0]) // 5
console.log(lengths[2]) // 3
const shortOnes = names.filter(n => n.length === 3)
console.log(shortOnes[0]) // bob
console.log(shortOnes[1]) // cat
console.log(names.find(n => n.length === 3)) // bob
console.log(names.some(n => n.length === 3)) // 1
console.log(names.every(n => n.length <= 5)) // 1
console.log(names.findIndex(n => n.length === 3)) // 1
const totalLen = names.reduce((acc, n) => acc + n.length, 0)
console.log(totalLen) // 11
const joined2 = names.reduce((acc, n) => acc + n, '')
console.log(joined2) // applebobcatView source on GitHubexamples/arrays/higher_order.ts