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

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
inbetween
and not end line, concat tooutput
- if
inbetween
and end line, returnoutput
and setinbetween
to false - if not
inbetween
and start line, setinbetween
to true - if not
inbetween
and 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.