Think Functional with Filter, Map and Reduce

Abinand Sivakumar
The Startup
Published in
7 min readSep 17, 2019

Hello functional programming beginners. I am going to walk you through three of the most common higher order functions that would help you kick your functional programming confidence into high gear.

Learning how to use the filter, map and reduce helper functions in JavaScript will be a great way to get started thinking about programs functionally and it can be a safe and reliable means to introduce that mode of thinking into the programs you write everyday either professionally or as a hobby.

The examples here would be in JavaScript just for convenience but it can be used in any programming language that supports higher order functions or passing functions as variables.

But on that same note, if your language of choice does allow passing of functions as variables, it doesn’t mean that the programs would be efficient because in some cases the compiler cannot optimize the code. For example, if you were to use higher order functions in PHP, since PHP is primarily object oriented, it would create objects on the fly. In most cases the performance impact is reasonable, and this is just a caveat.

And if you are just dipping your toes in functional programming, I would highly recommend getting familiar with JavaScript because it is practical and certainly ubiquitous. With JavaScript, you wouldn’t be second guessing if learning the constructs of the language are worth the value you get.

Alright, now before we discuss what filter, map and reduce do, let’s look at what they are generally. These types of functions are called Higher-Order Functions. That is just a fancy way of saying that these functions could take other functions as parameters.

A normal function and a higher order function
A regular function and a higher-order function

While learning your first programming language, you would have heard of basic data types. There are usually some basic data types that are supported out of the box like integers and strings, even lists and arrays in more high level programming languages. In languages that support the functional paradigm, functions are also treated as basic data types. You can assign functions to variables; they can be passed to other functions or returned as results.

JavaScript was not made with functional thinking from the start but it is loose enough to be able to treat it like a functional language. Also you might notice from the example code that I took some liberty with using array methods instead of passing the array as input but it is just semantics to make it simpler to read.

Alright now let’s go into the details of the common higher order functions starting from the easiest to the slightly less easy.

1) Filter

A filter, so conveniently named, is used to filter values from a list. In pure mathematical terms, it takes a list and a function as input and returns a new list based on the input function. The list in this case is nothing but a JavaScript array.

A filter
Filter takes a list and a function and gives a filtered list

Here is a sample in JavaScript (node.js) that takes a list of numbers from 1 to 10 and filters the odd numbers out. In order to tell what numbers need to be filtered, the function passed to the filter function needs to check the condition and return true if the value is “allowed”. The filter function uses this input function to check each value in the list and creates a new list out of the values that were allowed by the filter.

Sample code to filter only even numbers

2) Map

Filter is simple to use but also very powerful. We avoided using temporary variables, changing the values inside variables (mutating states) or even using a loop on the array. Aside from the silly variable names like f and A, the code is very expressive in what it does.

Using loops are a very common theme in most imperative programming languages that we take their existence for granted. But when you think functionally, loops are completely unnecessary. In fact they are so unnecessary that some functional languages do not even provide syntax to write loops. We already saw one way we can eliminate loops using filter but more often than not, you would find that map is a more suitable replacement instead of using for and while loops.

A map takes a list and a function and returns a new list. Just like filter, but the new list contains the same number of elements as the input list but they would be transformed by the input function we passed in.

A map transforms all inputs
Map transforms things in the input list based on the input function

Here is a sample code in JavaScript (node). We have an array of numbers from 1 to 10 and the input to the map triples all the values it receives. The output is a new array that is created by transforming the values in the input list to whatever the function returns.

Sample code to triple all values

In an imperative style of programming, we would declare loops, variables to iterate over the loops, counters, increments, decrements and more temp variables to do the same operation we just did with three lines of code. With map, we just specify what needs to happen and the rest takes care of itself. But we can get more clever with loops. Sometimes, it is not even necessary to map one list to another to get a result, especially when combining the elements inside the list that is returned after the map. To do that we could use…

3) Reduce

Reduce is the operation that is the most confusing initially. But as you use this more and more, it would become natural and obvious. The simplest way to think about it is as a merge operation. The reduce function takes an input list and an input function just like the other two helpers we saw. But it differs in two ways

  1. The output is not a list but a single value (usually, but you can get creative with it).
  2. The input function that is passed to the reduce function takes two values instead of one.
  3. Ok, so there is one more difference — it also takes an initial value.

That doesn’t sound simple at all. But we can break it down. First off the reduce performs squishing or merge of elements of the list.

A reducer used to combine elements of a list

You could think of the map operation from earlier as a special kind of reduce. The map creates a new list, the output, by concatenating the results returned from the function. But we didn’t ask it to concatenate. With reduce, we can tell how the output needs to be combined. The input function that we pass to the reduce is what says how to combine. And combining things requires two inputs and that is why the input function f, also known as the reducer, takes two arguments. Here is an example in JavaScript that sums all the values in an array.

Sample code to sum values in an array

You may notice that we pass a zero as input to the reduce. This is the initial value that is provided to the input. The reason we need an initial value is that when the reducer executes for the first time, on the first element in the list, it needs something to combine the value with.

So what happens to the value returned by the reducer function?- It is used as the initial value for the next element in the list. We have a special name for the initial value and it is called the Accumulator.

It is important to know which parameter in the inner reducer function is which. For JavaScript, the first parameter is considered as the accumulator. It is not obvious from this example on why the differentiation matters. So let’s take another example.

Remember the code to triple all values in the array we used for describing map? How about we sum all the elements of that result. We could do a map followed by a reduce with this sum reducer (this chaining of functions is another cool thing about functional programming) but we could also do both in one shot. Here’s the code

Map and Sum at the same time

It is important to triple the value b instead of the accumulator. Otherwise we would be tripling the sum after every intermediate result. So map is also just a reduce; however the combining logic of a map is predetermined — list concatenation, whereas we can specify any combining logic we want on the reduce.

Replacing loops in your day-to-day code would be the best place to experiment and learn functional programming. This is not a purist approach but doesn’t require too much learning to get a practical use out of it. Almost every language has some variation of these basic helpers and if not, you could definitely find optimized open source library implementations. Have fun!

--

--