Understanding JavaScript’s map, reduce, filter and sort.

If you have been doing some JavaScript, you’ve probably stumbled across some of them if not all. map, reduce and filter are usually considered confusing by beginners and in most cases, people avoid using them altogether. However, these methods are very powerful and flexible so spending some time understanding them will definitely pay off in the future.

In this post, I’ll try to shed some light on these powerful yet misunderstood JavaScript methods.

Array.map

map calls a provided call back function for each element in an array, in order, returning a newly created array.

If the above explanation isn’t clear enough, let’s see the map method in action.

var arr = [[12, 34, 54], [90, 67, 45], [34, 56, 87], [12, 333, 65]];

Let’s flatten this 2D array. By flatten I mean converting this 2D array into a regular one. How would you achieve this without using map? try to figure this out first on your own.

Time’s up!

Now, let’s flatten this beauty by using map in one single line!

console.log(arr.join(',').split(',').map(Number)); 
// output: [12, 34, 54, 90, 67, 45, 34, 56, 87, 12, 333, 65]

How cool was that? I don’t know you, but when I realized I could achieve this in one line using map my mind was blown!

So, if you’re asking yourself how could that work, let me explain what’s going on.

First, arr.join(‘,’) converts the whole array into a string, removing the brackets [] inside arr and replacing everything between numbers by a ,.

Next, arr.split(‘,’) splits (hence the name) the string where the comma is, and converts it into an array of strings like this [“12”, “34”, ….].

And last, map(Number) iterates through all the items inside arr and converts each string into a Number returning a newly created array which can be stored to a variable for later use.

Array.reduce

Imagine instead of flattening our arr you wanted to add all the items inside of each inner array, how could you achieve this in a simple manner?

Here’s where reduce() will shine!

The way I’d do it is as follows:

var arr = [[12, 34, 54], [90, 67, 45], [34, 56, 87], [12, 333, 65]];
var empty = [];
// create a function that adds 2 numbers
function add(a, b){
return a + b;
}
// and then call reduce() inside a for loop
for(var i = 0; i < arr.length; i++){
empty.push(arr[i].reduce(add, 0));
}
console.log(empty); 
// Output: [100, 202, 177, 410]

Again, the result can be stored in a variable to be used somewhere else in your code or you could also populate a new array with all the values that you get.

Note that this is slightly more complicated because we are manipulating a nested array, if arr was a flat array we would just have to call reduce on arr and pass it the function add making it quite convenient to write.

Array.filter

filter is another great Array method which comes very handy for sorting values in an array in a conditional form. For instance, imagine we would like to sort our arr by just keeping multiples of 2. We could do something as follows:

var arr = [[12, 34, 54], [90, 67, 45], [34, 56, 87], [12, 333, 65]];
// create a new array to hold the values 
var newArr = [];
// pass the multipleOfTwo function to our filter method
for(var i = 0; i < arr.length; i++){
newArr.push(arr[i].filter(multipleOfTwo));
}
function multipleOfTwo(val){ 
return val % 2 === 0;
}
console.log(newArr); 
// output: [[12, 34, 54], [90], [34, 56], [12]]

What filter basically does in the example above is, it checks every single value in an array and if that value’s remainder is equal to 0, it’ll push that value to newArr otherwise, it won’t so you just get back what you need.

Another great use for filter is when you need to sort an array of objects and return some of them depending on your condition, for example.

var users = [ 
{
"name": "Felipe",
"age": 30,
"email": "felipe@gmail.com"
},
{
"name": "Maria",
"age": 20,
"email": "maria@gmail.com"
},
{
"name": "Roger",
"age": 19,
"email": "roger@gmail.com"
},
{
"name": "Patrick",
"age": 39,
"email": "paddy@gmail.com"
}
];
var sortedByAge = users.filter(function(el){ 
return el.age >= 30;
});
console.log(sortedByAge);

This example will return two users object whom ages are greater or equal to 30. If each user object had also an id, you could simply sort this array by id and store the objects that meet this criteria inside a newly created array.

Array.sort

The sort method as the name states, sorts the values you pass to it through a callback function. However, if a callback function is not provided, elements are sorted by converting them to strings and comparing strings in Unicode code point order. For example, “Cherry” comes before “banana”. In a numeric sort, 9 comes before 80, but because numbers are converted to strings, “80” comes before “9” in Unicode order so keep this in mind while using this method.

In order to get the expected results, a callback function should be used (unless you want to compare elements in Unicode code point) as follows:

var arr = ["d", "x", "f", "a", "c", "b"]; 
var sorted = arr.sort(function(a, b){ 
return a > b;
});
console.log(sorted); 
// Output: ["a", "b", "c", "d", "f", "x"]

You can also reverse an array by doing this:

var arr = ["d", "x", "f", "a", "c", "b"]; 
var sorted = arr.sort(function(a, b){ 
return a < b;
});
console.log(sorted); 
// Output: ["x", "f", "d", "c", "b", "a"]

This comes very handy when used in conjunction with join() to reverse a string for example. Apart from sorting strings, sort can be used to sort arrays of numbers the same way.

var arr = [8, 3, 6, 1, 10, 0]; 
var sorted = arr.sort(function(a, b){ 
return a > b;
});
console.log(sorted); 
// Output: [0, 1, 3, 6, 8, 10]

Conclusion

These methods, when used properly have tremendous power achieving common tasks in JavaScript, so if you haven’t done it yet, start playing around with them so you get familiar with it’s inner workings and apply them to your projects as soon as you can so they become second nature to you!


Originally published at felipe-dev.me on February 5, 2016.