Implement a standalone reduce(arr, fn, initialValue) that behaves like Array.prototype.reduce. Don't call the built-in reduce or reduceRight.
It walks the array from left to right and keeps an accumulator, which is a running result. For each item it sets acc = fn(acc, value, index, arr). At the end it returns the final acc.
Starting value:
- If
initialValueis passed,accstarts as that value and the walk starts at index 0. Passingundefinedexplicitly still counts as passing a value. - If it's not passed,
accstarts as the first item and the walk starts at the next index. A single item is returned without callingfn. - With no items and no initial value, throw a
TypeError.
Edge cases from the spec:
- Holes in a sparse array (indexes that were never assigned, as in
[, , 3]) are skipped. They are never passed tofnand never used as the starting value. An array of only holes counts as empty. - The length is read once, before the walk. Items pushed onto the array during the walk are not visited.
- If
fnis not a function, throw aTypeError.
Input: reduce([1, 2, 3, 4], (sum, n) => sum + n, 10)
Output: 20
Input: reduce([2, 3, 4], (acc, n) => acc * n)
Output: 24starts with acc = 2, so fn runs twice
Input: reduce([], (a, b) => a + b)
Output: throws TypeError