Functional Programming in JavaScript(ES6+): map, filter
By: Woohyun Jang
Tags: Functional Programming, Underscorejs, Lodash, ES6, JavaScript

Map, Filter

We’ll be going to make some FP style utility functions ‘map’ and ‘filter’.

map & filter functions are very useful function in programming. you can use them in like ‘Lodash.js’, ‘Underscore.js’

Map

The ‘map’ function takes two arguments collection and iteratee . It creates a new array of values by running each element in the collection thru the iteratee.

The iteratee is called for each element and returns a calculated new value.

I made some mock data for the test and described the test case. In this case, the map function gets usersMock as a collection and returns their ids. So we expect to return [1, 2, 3, 4, 5, 6] .

function map(collection, iteratee) { const result = []; for (const value of collection) { result.push(iteratee(value)); } return result; } module.exports = map;

So the map function put the iteratee’s result to result traversing every elements.

Then the test case successes!

Filter

The filter function filters the collection according to predicate .

If we want to get a new array that only older than 20 in usersMock, we can write the test case like that.

test('filter', () => { expect(filter(usersMock, ({ age }) => age > 20).length).toBe(4); });

To succeed in that test case, we have to put the element only corresponding to the predicate traversing all elements like map function.

function filter(collection, predicate) { const result = []; for (const value of collection) { if (predicate(value)) { result.push(value); } } return result; } module.exports = filter;

Combine functions

Now that let’s solve the more complex question. If we want to get the user’s ids only younger than 30, how can I code it?

test('filter and map', () => { function solution(collection) {

// answer } expect(solution(usersMock)).toStrictEqual([1, 2, 3, 4, 6]); });

Without functional programming, we can make the solution function like that.

function solution(collection) { const result = []; for (const value of collection) { const {id, age} = value; if (age < 30) { result.push(id); } } return result; }

We can check the predicate while cycling, and put the element’s id to result. This solution works well, but as requirements get more complex, code will be difficult to read, difficult to maintain, and less reusable.

We already have two functions map&filter. we may implement the solution with them.

function solution(collection) { return map( filter(collection, ({age}) => age < 30), ({ id }) => id, ); }

In this code, the solution returns the map function’s result. The map function takes the filter’s result as a collection and it also takes the mapper that returns the user’s id.

So the map function will take the filtered collection and it’ll return the filtered collection by id.

Let’s compare the two solutions. FP is more readable and easy. If someone sees FP style solution, he can understand the code’s purpose easily. He can think just like that ‘map the filtered collection’!

The one more powerful thing about FP is reusability. The solution function consists of the map & filter functions.

When new requirements come in(ex. please give me the array of user’s names older than 25), we can use map & filter functions again and again.

Functional Programming is implemented by the combination of functions so it helps in safe and productive development.