Beginner's guide to using map(), filter() and reduce() in JavaScript
With examples, syntax and further reading materials.
It is quite confusing for beginners to differentiate between the functionalities of map, filter and reduce functions in JavaScript. That is understandable because of the fact that they have got quite a few uncanny similarities among them.
Similarities
- All the three are higher order functions in JavaScript.
- All of these are array methods/functions.
- All of these take an array and a modifying function as an input.
- All the three can be used interchangeable in a few cases.
Despite of having these things in common, it is important to know their peculiarities and where to use what. Given below an example for you to visually understand, what each of them does
map([๐ฝ, ๐ฎ, ๐], cook)
=> [๐ฟ, ๐, ๐ณ]
filter([๐ฟ, ๐, ๐ณ], isVegetarian)
=> [๐ฟ, ๐ณ]
reduce([๐ฟ, ๐ณ], eat)
=> ๐ฉ
MAP
map takes in an array and a function, and returns an array (of the same size as the input array) with some modifications. map() is essentially used when we want to output a modified array that has equal number of elements as the input array.
Example #1
Lets say, you get an array of numbers and you want to triple the original values of the array i.e. [2,3,4,5] becomes [6,9,12,15] and likewise.
const input = [2,3,4,5];
function triple(x)
{
return x * 3;
}
const output= input.map(triple);
// output = [6,9,12,15]
triple()
is a function that takes an integer input x
and returns its triple 3*x
. In the last line of the example we have used triple inside the map to apply the effect of triple()
function to each of the element of the input
array.
map()
essentially is used as a prototype function to arrays, that takes in another function f
as its argument and injects the effects of function f
to each of the elements of the array.
output
is essentially an array with equal number of elements as the input
array but with the values changed to triple of the original element.
Another way of writing the last example
One can also write the whole body of the triple()
function inside the parenthesis of the map function. i.e the whole function body can be passed as an argument to map()
const input = [2,3,4,5];
const output = input.map(
function triple(x)
{
return x*3;
}
)
This can further be even more simplified as such -
const output = input.map((x)=>x*3);
the arrow function is an ES6 feature. Learn about it in this blog here.
One doesn't even need to write the return
keyword explicitly when the function has just one line of code inside it.
FILTER
filter takes in an array and a function, and returns a filtered array with less number of elements than the input array.
The filter() method takes each element in an array and it applies a conditional statement against it. If this conditional returns true, the element gets pushed to the output array. If the condition returns false, the element does not get pushed to the output array.
All problems related to filter() would be in the general structure of : Given an array, create an array with all the elements that fulfill a certain criteria.
Example #1
Problem : Given an integer array, create a new array with all the elements that are divisible by three.
const numbers = [2,3,5,6,9,10,11,12]
const output = numbers.filter(item=> item%3 === 0);
In the above code, the function inside filter can also be written as
function isDivisiblebyThree(item)
{
return (item%3 === 0)
}
which is same as
function isDivisiblebyThree(item)
{
if(item%3 === 0)
return true;
else
return false
}
output = [3,6,9,12]
REDUCE
Reduce is the most important yet very easily misunderstood method in JavaScript. This is because of the fact that it's not so intuitive as map and filter, atleast not on the first look.
The important thing to consider is that reduce function essentially returns just a single object after it has done its work unlike map and filter that throw out an array.
According to mdn web docs :
The reduce()
method executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is a single value.
Let's say you have an array of numbers nums
, that you want to add up to a given value initialValue
(which is 10 in the example), such that at the end, accumulator will be the sum of all the values of the array and the initial value.
Let's first use a for loop to achieve this task
let initialValue = 10;
let accumulator = initialValue;
let nums = [1,2,3,4,5];
for(n of nums)
{
initialValue = initialValue + n;
}
The above code can be written using a reduce function as follows
nums.reduce((accumulator,currentValue)=>{
return (accumulator + currentValue);
},initialValue)
the reduce function will store the value (accumulator+currentValue)
returned after each iteration of the callback function into the accumulator itself. The initialValue is the value the accumulator initially starts with.
There are quite a few syntax when it comes to using reduce() method
// Arrow function
reduce((previousValue, currentValue) => { /* โฆ */ } )
reduce((previousValue, currentValue, currentIndex) => { /* โฆ */ } )
reduce((previousValue, currentValue, currentIndex, array) => { /* โฆ */ } )
reduce((previousValue, currentValue) => { /* โฆ */ } , initialValue)
reduce((previousValue, currentValue, currentIndex) => { /* โฆ */ } , initialValue)
reduce((previousValue, currentValue, currentIndex, array) => { /* โฆ */ }, initialValue)
// Callback function
reduce(callbackFn)
reduce(callbackFn, initialValue)
// Inline callback function
reduce(function(previousValue, currentValue) { /* โฆ */ })
reduce(function(previousValue, currentValue, currentIndex) { /* โฆ */ })
reduce(function(previousValue, currentValue, currentIndex, array) { /* โฆ */ })
reduce(function(previousValue, currentValue) { /* โฆ */ }, initialValue)
reduce(function(previousValue, currentValue, currentIndex) { /* โฆ */ }, initialValue)
reduce(function(previousValue, currentValue, currentIndex, array) { /* โฆ */ }, initialValue)
Further Readings :
for Map method : https://developer.mozilla.org/JavaScript/Reference/Global_Objects/Array/map
for Filter method : https://developer.mozilla.org/JavaScript/Reference/Global_Objects/Array/filter
for Reduce method : https://developer.mozilla.org/JavaScript/Reference/Global_Objects/Array/Reduce
Conclusion
The clarity of using map, filter and reduce methods or any new concept in general comes with more and more practice. I would suggest readers to learn by implementing anything that doesn't fully make sense at first reading.
That is it for this blog. If you liked the content and it helped you in any way, please leave a like. Very happy to have written my first blog on Hashnode.
Follow me on twitter for short content related to JavaScript and web development @thinwhiteframe
Thanks and Happy Coding.