Even if you don’t know what functional programming is you’ve probably been using map, filter and reduce just because they’re so incredibly useful and make your code stink less by allowing you to write cleaner logic.
Disclaimer: the title of this article is ‘JavaScript Functional Programming’ but I won’t be diving too deep in to that topic, we’ll be looking at map, filter and reduce.
It’s basically a marketing trick to raise awareness of a really cool world of coding called functional, maybe you never heard of it or maybe you heard of it but never gave it much thought.
If you’re suddenly interested in finding out more about functional programming check out Professor Frisby’s Mostly Adequate Guide to Functional Programming (Link)
or
Functional-Light JavaScript by the awesome Kyle Simpson (Link)
or
take a look at Eric Elliott (Link) the dude’s a legend(!!!) and talks about functional programming often.
Even if some of these concepts fly over your head the first time you read them, don’t worry, that’s natural, keep at it and soon you’ll be reaping the rewards.
In my opinion, the most important thing here is to introduce you to new approaches that will help you write better JavaScript code.
Let’s move on to the stars of this article…
Map
Let’s take a look what MDN says ‘map’ is (Link):
Description:
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
Example:
const numbers = [2, 4, 8, 10];
const halves = numbers.map(x => x / 2);
// halves is [1, 2, 4, 5]
Nothing fancy here, we’re just going over the values in ‘numbers’ array, halving them and creating a brand new array with the halved values (big reveal: the array with halved values is called ‘halves’. SHOCKER!)
map is used when you have an array of stuff ( scientific term ) and you want to do something ( another scientific term ) for every item in that array.
For a more in depth look at map go over to MDN (Link)
Filter
What does MDN think filter is? (Link)
Description:
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
Example:
const words = [
"spray",
"limit",
"elite",
"exuberant",
"destruction",
"present",
];
const longWords = words.filter(word => word.length > 6);
// longWords is ["exuberant", "destruction", "present"]
Just like map ‘filter’ is nothing special. It’s going over values in ‘words’ array checking which values pass the test, in this case which value has length greater than 6 and then returns a new array with those values
For a more in depth look at map go over to MDN (Link)
Reduce
And now we’ve arrived at the fun part and the inspiration for this article.
reduce is incredibly versatile and flexible! It can be used in a tonne of scenarios, it’s a damn shame that
it’s mostly used to get the sum of numbers in an array or the “more advanced version” ( *sarcasm* ) in an array of
objects get the sum of a certain property.
MDN! What’s your take on reduce? (Link)
Description:
The reduce() method applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.
Example:
const total = [0, 1, 2, 3].reduce((sum, value) => sum + value, 1);
// total is 7
See that up there? The most common reduce example known to man and that wouldn’t be a problem if developers expanded on it rather than stopping there.
What I noticed happening with developers and reduce is that they either don’t need to sum up some numbers so they
forget reduce exists or they remember reduce exists only when they need to sum up some numbers
but ( as was implied before ) reduce can do so much more than just sum stuff.
The really cool thing about reduce is that it passes the result of one callback function invocation to the next one allowing us to do some crazy ass shenanigans like…
Compose Functions
The example for composing functions using reduce we’ll be looking at I jacked from Eric Elliott and his post about reducers (Link), which I can’t recommend enough.
Eric Elliott always produces quality content and you should definitely follow him on every possible platform!
The part that’s most interesting to us is this one:
const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);
That up there is poetry!
‘compose’ is partially applied ( curried ) with functions that will do their work and pass along the results to
the next function in line, notice the usage of rest parameters so that we can compose as many functions as we want
and all of them will be put in the ‘fns’ array. Baller!
Then we feed it the initial value ( x ) or rather the value on which you’ll apply actions — compose functions.
After that we reduceRight the array of gathered functions with the initial value — x, this is the same as reduce
but starts at the end of the array and moves to the start because that is how ‘compose’ works if the opposite is
more natural to you than you want to pipe functions.
Example usage:
const add1 = n => n + 1;
const double = n => n * 2;
const add1ThenDouble = compose(
double,
add1
);
add1ThenDouble(2); // 6
// ((2 + 1 = 3) * 2 = 6)
Awesome!
Chaining Promises
The example for chaining promises using reduce I jacked from Bobby Brennan and his excellent post about promise patterns and anti-patterns (Link). Check it out!
The interesting part:
let itemIDs = [1, 2, 3, 4, 5];
itemIDs.reduce((promise, itemID) => {
return promise.then(_ => api.deleteItem(itemID));
}, Promise.resolve());
The code up there translates to:
Promise.resolve()
.then(_ => api.deleteItem(1))
.then(_ => api.deleteItem(2))
.then(_ => api.deleteItem(3))
.then(_ => api.deleteItem(4))
.then(_ => api.deleteItem(5));
Look at how nice and clean reduce makes the code, now imagine how much cleaner it would get if it was an array of 40 or more id’s!
It’s not even a complicated example, it’s really straightforward, that’s what makes it so bitchin’!
Call to Action
We saw some really cool and creative uses of map, filter and reduce… who are we shitting here? The cool and
creative examples were only for reduce but never mind that!
If you’ve stumbled upon some interesting ways map, filter or reduce were used send me an email, I’m sure there are heaps of practical ways these 3 can be used!