Say goodbye to loops with ‘reduce’ ????
If you’re starting with functional programming and don’t know where to continue after map and filter, go with reduce.

–Do you insist on using the image of the cat? –Yes, I do. Reflects the essence of functional programming. Source: https://farm6.staticflickr.com/5185/5619954191_565779cf5d_b.jpg
Reduce is the holy grail of versatility when it comes to processing objects and lists. Its properties allow you to implement practically anything:
- you can determine your initial value
- you control the output type
- it walks through all elements
This means you get to control what goes in, what goes out and what is inside at all times. With that in mind, you can do whatever pure operation you like during the iteration as it is still you controlling the output. For example, here is how to implement filter using reduce:
// JS
const filter = (fn, list) =>
list.reduce((acc, next) => (fn(next) ?
acc.concat(next) : acc), []);
// Haskellfilter’ :: (a -> Bool) -> [a] -> [a]
filter’ fn = foldr (\x xs -> if fn x then x:xs else xs) []The same can be done for map:
// JSconst map = (fn, list) =>
list.reduce((acc, next) => acc.concat(fn(next)),
[]);
// Haskellmap’ :: (a -> b) -> [a] -> [b]
map’ fn = foldr (\x xs -> fn x : xs) []Keep in mind that reduce can produce any value type, so you can do iterations requiring you to remember some intermediate value. For example, if we wanted to select lines placed in between two other lines, we could have an object of { output: “”, inbetween: false }. Then:
- if
inbetweenand not end line, concat tooutput - if
inbetweenand end line, returnoutputand setinbetweento false - if not
inbetweenand start line, setinbetweento true - if not
inbetweenand not start line, just return accumulator
Just take the output property when finished and you’re done.
So next time you would want to use a for loop, go for reduce instead! If it is the preferred way in your language, of course.