Vencovsky
Vencovsky

Reputation: 31585

Array .filter and .map OR .map with a if condition

Recently I was doing some sort of filter to an array and I came up with two cases and I don't know which one to use.

In terms of performance, which is better to use.

arr.filter(someCondition).map(x => x.something)

Or

arr.map(x => {
    if(someCondition) {
        return x.something
    }
})

One thing to notice is that I'm using react, so have undefined values in the returning array (don't return any thing inside .map), it's totally acceptable.

This involves a lot of questions like, how many elements you have in the array and how many you of then will pass the condition and that is what make be wonder which one is better.

So, considering n elements and cases where all elements pass the condition and also that no elements pass the condition, which one have better performance?

.filter().map() OR .map with if inside?

Upvotes: 2

Views: 13028

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1074148

First: It's really unlikely to matter.

But: Only because it's okay in your case to have undefined in the result array, the second one will be faster.

Let's compare:

The first way, filter has to make a pass through the entire array, creating a new array with the accepted entries, then map has to make a pass through the new array and make a new array of the something properties.

The second way, map makes one pass through the array, creating a new array with the something properties (or undefined for the ones that would have been filtered out).

Of course, this assumes you aren't just offloading the burden elsewhere (e.g., if React has to do something to ignore those undefineds).

But again: It's unlikely to matter.

I would probably use a third option: Build the result array yourself:

const result = [];
for (const x of arr) {
    if(someCondition) {
        result[result.length] = x.something;
    }
}

That still makes just one pass, but doesn't produce an array with undefined in it. (You can also shoehorn that into a reduce, but it doesn't buy you anything but complexity.)

(Don't worry about for-of requiring an iterator. It gets optimized away in "hot" code.)

Upvotes: 6

Dixy Xavier
Dixy Xavier

Reputation: 677

You could use reduce function instead of map and filter and it wouldn't return you undefined like when you use map and if.

arr.reduce((acc, x) => (someCondition ? [...acc, x.something] : acc), [])

or

arr.reduce((acc, x) => {
  if (someCondition) {
    acc.push(x.something);
    return acc;
  } else return acc;
}, []);

As @briosheje said smaller array would be a plus. As it reduces number of rerendering in your React app where you use this array and it is unnecessary to pass undefined. Reduce function would be much more efficient, I would say.

If you are wondering why I have written 1st one using spread operator and 2nd one without it is because the execution time taken for 1st one is more compared to 2nd one. And that is due to spread operator as it is cloning 'acc'. So if you want lesser execution time go for 2nd one or else if you want lesser LOC go for 1st one

Upvotes: 4

Related Questions