Understanding the .map(), .filter() and .reduce() array methods in Javascript.

Understanding the .map(), .filter() and .reduce() array methods in Javascript.

Arrays are one of the most used data structures in Javascript, from storing basic data in our code to getting results from API calls. As Javascript developers were always working with arrays and carrying out some form of operation on them.

The .map(), .reduce() and .filter() are some of the lesser-known array methods released in ES6, that uses a more functional and cleaner approach to carry out array operations.

In this article, we’ll be taking a detailed look at how these array methods work and how we can use them to carry out some basic operations.

Overview

First a brief look at what these array methods do.

The .map() method returns a new array where each element have gone through an operation of some kind.

The .filter() method returns a new array containing only array elements that passed a specific condition.

The .reduce() method reduces all the elements in the original to a single value.

These array methods are Higher Order Functions, meaning they take callback functions as parameters.

The .map() method

The .map() method returns a new array that contains the result of applying an operation on each of the original array elements.

The .map method accepts a callback function as a parameter and an important parameter for the callback function is the element parameter, the element parameter is processed by the callback function and returned an element to the new array.

Syntax for the .map() method

Array.map(function (element) {
    //operation on element
})

//using arrow function
Array.map(element => {
    //operation on element
})

Using the .map() method

let numbers = [24, 11, 8, 13]

const double = numbers.map(number=> score * 2)
console.log(double) 
// outputs [ 48, 22, 16, 26 ]

When we run the code above. The .map() function loops through the numbers array, assigns the current element in iteration as number, carries out the operation number * 2, and then finally inserts this new value to the new array.

Note that the .map() method will always return an array of the same length as the original array.

For the rest of this tutorial, we'll be working with an array of objects, that contains the name, occupation and score of a group of employees.

const employees = [
  {
    name: "Peter",
    score: 25,
    occupation: "Engineer"
  },
  {
    name: "Judy",
    score: 30,
    occupation: "Banker"
  },
  {
    name: "Jarvis",
    score: 40,
    occupation: "Doctor"
  },
  {
    name: "Paul",
    score: 65,
    occupation: "Engineer"
  }
]

The .map() method can also be used to extract specific data from an array With the .map() method, we can get the names of all the employees to a new array.

const names = employees.map(person => person.name)
console.log(names) 
//returns ["Peter","Judy","Jarvis","Paul"]

More callback parameters

The .map() callback function can take more parameters that you might find useful when carrying out array operations.

Array.map((element, index, array) {operation})

The element parameter is used to access the current element in iteration.

The index returns the index of the current element in iteration

the array returns the complete original array.

I personally haven't seen any use case for the array parameter. If you have seen please comment below.

The .filter() Method

The .filter() returns a new array containing only elements that passed the condition passed in the callback function.

Syntax for the .filter() method

Array.filter(element => {
    //conditon
})
let numbers = [24, 11, 8, 13]

const filter =  numbers.filter(number => number > 10)
console.log(filter)  
// output [24,11,13]

When we run the code above the .filter() method loops through the numbers array, and checks if the current number is greater than 10, if true the number is added to the new array.

Using the .filter() method

We can use the .filter() method to get the array of employees who are engineers from our data above.

const allEngineers = people.filter(person => person.occupation === "Engineer")
console.log(allEngineers)
//Outputs 

[
  {
    name: "Peter",
    score: 25,
    occupation: "Engineer"
  },
{
    name: "Paul",
    score: 65,
    occupation: "Engineer"
  }
]

Optional callback parameters

The .filter() callback function just like the .map() can also take more than just the element parameter as an argument and they also serve the same purpose.

Array.filter((element, index, array) {condition})

The .reduce() method.

The .reduce() method is used to combine all the elements in an array to get a value. It evaluates all of the elements in the array to return a single value.

The .reduce() method is a little more complicated than the other two mentioned above because its callback function requires a specific parameter known as the “accumulator” which holds the total value during the operation and returns it after the operation is completed. This "accumulator" parameter is used in the reducer function.

Syntax for .reduce() method

Array.reduce((accumulator, element) {
    //reducer
}, initial value)

Using the .reduce method to get the sum of numbers.

let numbers= [24, 11, 8, 13]

const sum =  numbers.reduce((sum, number) => {
  return sum + number
}, 0)

console.log(sum)  
// outputs 56

When the code above runs the .reduce() method first set the value of sum to 0 which was provided as the initial value and then loops through the array, on every iteration, it adds number to the value of sum, and after the last element returns sum which in our case is 56.

While the initial value might be optional it's always advisable to specify it, to avoid getting a TypeError in the case of an empty array. We get the error message below.

Uncaught TypeError: Reduce of empty array with no initial value

Chaining Methods

One of the pros of using these array methods is the ability to chain them. Since unlike the .forEach() method these array methods return a new array, we can chain them to get a combo method.

Chaining is combining array methods to perform operations on them and get a final return value.

Using chaining we can get the names of employees who scored above 35.

const passed= people.filter(person => person.score > 35)
  .map(person => person.name)

console.log(passed)
 // outputs ["Judy","Jarvis","Paul"]

In the code above the .filter() operation is carried out first on the array which returns an array of employees whose score is above 35 then the .map() method returns their name as the final value of the operation.

We can also get the sum of the scores of engineers only.

const engineersScore= people.filter(person => person.occupation === "Engineer") //return an array of engineers only
    .map(person => person.score) //returns the array of engineers score
    .reduce((sum, element) => sum + element) //sums up the score.

console.log(engineersScore)
//outputs 90

Conclusion

The best way to master new concepts is by using them. Try using these methods in place of the .forEach() when possible.

Feel free to comment below if you have any feedback and please share with other Javascript developers.

Let's Connect on Twitter

Resource I used

MDN