MiddleCodeCommonNot answered yet
Rewrite an accumulating loop with reduce, then implement your own reduce
An accumulating for loop sums an array. Rewrite it as a single reduce call, then implement your own myReduce with the same shape as the standard library's.
Constraints:
- The rewrite must be one expression using
reduce. myReducetakes an initial result and a combining closure; do not call the built-inreduce.
extension Array {
func myReduce<R>(_ initial: R, _ next: (R, Element) -> R) -> R {
// your code here
}
}
Write the implementation.
The loop becomes xs.reduce(0, +). reduce folds a sequence into a single value by threading an accumulator through a combining closure. Your myReduce starts from initial, iterates over self, reassigns result = next(result, element) per element, and returns the final accumulator.
- ✗Confusing
reduce(fold to one value) withmap(element-wise transform) - ✗Forgetting
reduceneeds an initial accumulator value - ✗Thinking
reducemutates the source sequence
- →When is
reduce(into:)preferable toreduce(_:_:)? - →How does
reducediffer frommapfollowed by a summation?
The loop for n in xs { sum += n } becomes xs.reduce(0, +). The hand-written version mirrors the same fold:
extension Array {
func myReduce<R>(_ initial: R, _ next: (R, Element) -> R) -> R {
var result = initial
for element in self {
result = next(result, element)
}
return result
}
}
[1, 2, 3, 4].myReduce(0, +) // 10
reduce neither transforms nor mutates the array: it starts from initial and, for each element, reassigns the accumulator to the result of next, returning the final value.