Reputation: 31585
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
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 undefined
s).
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
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