
I know it is 2019 and it has been a while since ES5 came out but there are still times when .reduce() makes me lookup the documentation on MDN. And, well, different people understand concepts differently so here is my stab at explaining the map, filter and reduce methods hoping it will help someone. My goal here is to provide some real-world examples since I find there is a world of difference between what we read and the challenges we face when implement.
.map()
The map method iterates through each value in an array and returns the modified values in a similar array.
For example, consider you’d like to iterate through each value in an array and double it’s value:
arr = [1, 2, 3, 4, 5]arr.map(value => value*2 );Result: [2, 4, 6, 8, 10]
It is important to note though that the original array arr does not change. It still contains the same values. If you’d like to get the value of the new array, then you can simply return the value from the .map() to another variable like so
let newArr = arr.map(value => value*2 );console.log(newArr);Result: [2, 4, 6, 8, 10]
Now, let’s make it a touch interesting. You’d like to push the old and the new value as an array into the newArr making it an array of arrays. In that case, you can do something like this:
let newArr = arr.map(value => {
return [value, value*2]
});console.log(newArr);Result: [[1, 2], [2, 4], [3, 6], [4, 8], [5, 10]]});
.filter()
Sometimes, you need to filter out the values from an array of objects using a certain key, value pair as the filter or you’d like to just filter out an array of numbers based on a certain criteria. The .filter() method helps us do just that. Let’s start with the simpler scenario of filtering out values based on a certain criteria below:
let arr = [10, 32, 64, 40, 25, 8, 37]let newArr = arr.filter(value => {
if (value > 30) { return value }
});console.log(newArr);Result: [32, 64, 40, 37]
Now, consider if we had an array of objects and needed to filter it:
let arr = [
{
key: 1,
count: 10
},
{
key: 2,
count: 32
},
{
key: 3,
count: 64
},
{
key: 4,
count: 40
},
{
key: 5,
count: 25
},
{
key: 6,
count: 8
},
{
key: 7,
count: 37
}
]let newArr = arr.filter(value => {
if (value.count > 30) { return value }
});console.log(newArr);Result: [
{
key: 2,
count: 32
},
{
key: 3,
count: 64
},
{
key: 4,
count: 40
},
{
key: 7,
count: 37
}
]
.reduce()
Lastly, let’s get to reduce. Reduce helps us iterate through an array of values and return a single value. It is the most versatile and perhaps the most difficult to understand of the 3 methods we are covering today.
Let’s start with a basic example of adding the elements of an array and returning a single value.
let arr = [4, 7, 2, 18, 21]arr.reduce((accum, value) => {
return accum + value
})Result: 52
We could also do some fun stuff with reduce such as implementing .map() and .filter() using reduce. The reduce method originally takes a function and a (optional) start value separated by commas. In the examples below, we have provided an empty array as the start value.
If the start value is not provided, then the first value within the input array (here arr) is used and the value variable contains the next value within the array.
Below are the solutions for the .map() and .filter() implementations using .reduce():
let arr = [4, 7, 2, 18, 21]arr.reduce((accum, value) => {
accum.push(value*2)
return accum
}, [])Result: [8, 14, 4, 36, 42]arr.reduce((accum, value) => {
if (value > 5) { accum.push(value) }
return accum
}, [])Result: [7, 18, 21]
The above examples show us how versatile .reduce() is. However, it should always be an optimization consideration about which strategy to use when. Just because we happen to have a hammer does not mean that it is the best tool for every use.
Bonus method! Yay!
If you have stuck with me so far, here is another method which can be very useful when working with loops, arrays and using arrays within loops. Remember the example above with .map() when we created an array of arrays? For some use cases, we might need to make it into a single array. We can do so with the help of .flatMap()
.flatMap()
This method does the same thing as .map() with an additional step of flattening the end array by a single level to reduce complexity. It helps us simplify things when we are working with loops within loops and dealing with large and varied types of data. Here’s an example of the original implementation of .map() and how the resultant array changes when we change just a few letters and use .flatMap().
let arr = [4, 7, 2, 18, 21]let newArr = arr.map(value => {
return [value, value*2]
});console.log(newArr);Result: [[4, 8], [7, 14], [2, 4], [18, 36], [21, 42]]arr.flatMap(value => {
return [value, value*2]
})Result: [4, 8, 7, 14, 2, 4, 18, 36, 21, 42]
So, there it is. A short explanation about the Javascript methods which help us simplify our lives and write easier to understand code right off the bat.
Let me know your thoughts about this post and leave any comments/suggestions below!
