JavaScript map and forEach - a comparison

2019, Oct 22

In this blog we are going to talk about the usage of these higher order functions.

I am always asked about the usage of these function by my colleagues and friends. Sometime we get confused while using these functions to do some operations on the array. We have many questions in our mind while using these. Let's discuss them with simple examples.

TABLE OF CONTENTS

  1. Important notes on these higher order functions.
  2. Description with an example - use case - 1.
  3. Observation.
  4. Performance comparison.
  5. Description with an example - use case - 2.
  6. Take away.
  7. Conclusion.

Important notes on these higher order functions:

  • Used to do operations on the array.
  • Gives the real taste of functional programming.
  • Helps us to write declarative program. We are telling computer what we want it to do rather how to do it.
  • Declarative approach is easily optimisable at compiler end.
  • We can write pretty cleaner, shorter, more expressive, concise and less error prone code.
  • It is easier to maintain and easier to debug.

We have an array as below.

const employee = [
{
  companyName: "xyz.com",
  age: 26,    
  role: "Software Engineer",    
  salary: 35000,    
  timeSpent: 3  
},  
{    
  companyName: "My Traveler",    
  age: 28,    
  role: "Senior Software Engineer",    
  salary: 65000,    
  timeSpent: 2  
},  
{    
  companyName: "Product Wheel",    
  age: 31,    
  role: "Lead Engineer",    
  salary: 90000,    
  timeSpent: 3  
},  
{    
  companyName: "Make My Budget",    
  age: 35,    
  role: "Consultant",    
  salary: 125000,    
  timeSpent: 4  
}
];

Our requirement is to find the names of all companies from this array

// ["xyz.com", "My Traveler", "Product Wheel", "Make My Budget"]

Those who unaware of these awesome(higher order) functions they may use the for loop.

const companies = [];

for(i=0; i < employee.length; i++) {
  
  const company = employee[i].companyName;
  companies.push(company);

}

console.log(companies); 

// ["xyz.com", "My Traveler", "Product Wheel", "Make My Budget"]

Someone may use forEach with a confusion.

const companies = [];

function getCompaniesName(emp) {
  
  const company = emp.companyName;
    
  companies.push(company);
}

employee.forEach(getCompaniesName);

console.log(companies);

// ["xyz.com", "My Traveler", "Product Wheel", "Make My Budget"]

Note* :- Return type of the forEach is undefined. You can not return anything from forEach. Even if you return something from it, will be discarded.

What we have observed from both of the cases.

  1. We are getting the company name by doing imperative programming. We are focusing on "how" rather than "what".
  2. Behavior of forEach is stopping us from using it to get the array of company name. Because it's return type is undefined.
  3. We ended up with writing many lines of code.

Which function will be fit here for this scenario? Map?

const companies = employee.map(emp => emp.companyName);

console.log(companies);
//["xyz.com", "My Traveler", "Product Wheel", "Make My Budget"]

What??????? Only one line of code????????

Reason behind using map function here:

  1. Allow us to write declarative code. We know "what" we want, rest of the thing will be taken care by map function.
  2. The return type of map is an array. It always return a new array with out effect the actual array.
  3. Number of line is much lesser as compare to for loop and forEach. It is cleaner, shorter and expressive.

Performance Comparison

Jsperf is a great tool to check and compare the performance of your code. I tested this code in my system and got the below result:

perf result

You can find the test and test result here(https://jsperf.com/hoctest/1).

As you can see, for loop and forEach much(40% - 41%) slower than the map function. Results may vary system to system but you will get map function faster always. You can try it on your system and share the result.

Lets go to the next scenario.

We have a requirement of getting yearly packages of the companies employee was getting.

In the array, monthly salary of an employee has been given. We have to multiply 12 with each salary to get the yearly package. So our output should be like:

[  
  {
    companyName: "xyz.com", 
    salary: 420000
  },  
  {
    companyName: "My Traveler", 
    salary: 780000
  },  
  {
    companyName: "Product Wheel",
    salary: 1080000
  },  
  {
    companyName: "Make My Budget",
    salary: 1500000
  },
]

Here, we need an array with some transformations. With some confusion, again I am decided to use the forEach for this operation. This time, I have knowledge that return type of forEach is undefined. So what???

function getCompanyPackages(emp, index){
  employee[index] = {
    companyName: emp.companyName,
    salary: emp.salary * 12
  }
}
employee.forEach(getCompanyPackages);

Wait! Wait! Wait! Wait! What we are doing here?

We are not returning anything. That is great. But we are mutating the original array. Lets print the original array employee:

console.log(employee);
[  
  {
    companyName: "xyz.com", 
    salary: 420000
  },  
  {
    companyName: "My Traveler", 
    salary: 780000
  },  
  {
    companyName: "Product Wheel",
    salary: 1080000
  },  
  {
    companyName: "Make My Budget",
    salary: 1500000
  },
]

We are getting the desired output on sacrificing the original data of input. That's not great at all. We can use the original employee object any more in our code. Because it is mutated.

Lets try to use map function here:

function getCompanyPackages(emp){
  return {
    companyName: emp.companyName,
    salary: emp.salary * 12
  
  }; 
}


const companyPackages = employee.map(getCompanyPackages);

We will get the desire output without affecting the original input , i.e employee array.

console.log(companyPackages);[
  {
    companyName: "xyz.com",
    salary: 420000
  },
  {
    companyName: "My Traveler",
    salary: 780000
  },
  {
    companyName: "Product Wheel",
    salary: 1080000
  },
  {
    companyName: "Make My Budget",
    salary: 1500000
  },
]

Also you can log the employee array and check that using of map function didn't change it.

What is the take away from this example

Question arises here, where and when to use forEach and map ?

Use forEach when you are trying to iterate over the array to do something with it, like saving it to the database or logging it.

Use map when you want to transform elements in an array.

Conclusion

If you still have some confusion, try to read more articles on these higher order function. Always try to think twice before using these. Ask question to yourself that what you are trying to achieve. Then use these functions accordingly. We need to use these functions not to make our code complex, to make our life easy.


More blogs on the JavaScript

  1. How to deal with falsy values in JavaScript.
  2. JavaScript Object - Add member conditionally using spread operator.