JS array : filter() with map() vs forEach()

Viewed 7494

Which is more optimized way .filter() + .map() OR .forEach() ?

Here is a sample array of objects:

var personnel = [
    {
        id: 5,
        name: "Luke Skywalker",
        pilotingScore: 98,
        shootingScore: 56,
        isForceUser: true,
    },
    {
        id: 82,
        name: "Sabine Wren",
        pilotingScore: 73,
        shootingScore: 99,
        isForceUser: false,
    },
    {
        id: 22,
        name: "Zeb Orellios",
        pilotingScore: 20,
        shootingScore: 59,
        isForceUser: false,
    },
    {
        id: 15,
        name: "Ezra Bridger",
        pilotingScore: 43,
        shootingScore: 67,
        isForceUser: true,
    },
    {
        id: 11,
        name: "Caleb Dume",
        pilotingScore: 71,
        shootingScore: 85,
        isForceUser: true,
    },
];

And let say we want to get the final array giving only name and id where isForceUser=true

[ { id: 5, name: 'Luke Skywalker' }, 
  { id: 15, name: 'Ezra Bridger' }, 
  { id: 11, name: 'Caleb Dume' } ] 

Now there are 2 ways ti solve it :

  1. By using .filter()+.map(), as shown below:
var APersonnel = personnel
                    .filter((person) => person.isForceUser)
                    .map((person) => ({ id: person.id, name: person.name }));
  1. By using .forEach() and pushing a new object:
var BPersonnel = [];
personnel.forEach((person) => {
    if (person.isForceUser) {
        BPersonnel.push({ id: person.id, name: person.name });
    }
});

Which one of the solutions defined above is better and why?

3 Answers

These are not the things you should seek performance improvements in. You are talking about 'personnel' here. Which is a fairly limited array set, I imagine. If you are having performance issues, I suggest you use the chrome dev performance tab to see what's causing it.

To answer your question, filter + map is semantically easier for the eye, which again is a personal opinion. Strictly performance wise the forEach is faster, where most likely a basic of for loop is even faster. But again, these are a few milliseconds we are talking about. Which does not justify the cost of rewriting :)

Another way can be to use reduce, less code, and only one loop:

const APersonnel = personell.reduce((acc, person) => {
  if (person.isForceUser) {
    acc.push({ id: person.id, name: person.name });
  }
  return acc;
}, []);

The best way is using foreach. Because map and filter are going to create two arrays. foreach doesn't create arrays. So foreach is the best one. look at those statements bellow,

The filter() method creates a new array with all elements that pass the test implemented by the provided function.

The map() method creates a new array with the results of calling a provided function on every element in the calling array.

I could be wrong, but I'm guessing forEach would be better.

In the first scenario, you are looping across 5 items, and then again across 3 items. In the second scenario you are just looping across 5 items. And the if in the foreach is effectively being done in the filter anyway.

There may be an exception if you're working with an extremely large set of data because you would have both arrays in memory, but for anything short of that, I would recommend forEach

Related