Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript JavaScript Array Iteration Methods Combining Array Methods Combining filter() and map()

Sara Masek
seal-mask
.a{fill-rule:evenodd;}techdegree
Sara Masek
Front End Web Development Techdegree Student 11,513 Points

Why does filter have to come first in the chain sequence?

I was just wondering why when chaining map and filter together, why does .filter have to come first? My original solution had .map chained first, and all it returned was an empty array (this is assuming all code within the functions was the same as in the video, the only difference being that I switched the .filter and .map positions).

3 Answers

Dane Parchment
MOD
Dane Parchment
Treehouse Moderator 11,077 Points

Okay. Just so you are aware, filter doesn't always have to come before map when chaining these array methods together. It's just that in this use case it makes sense to do so.

Consider the fact that map will loop through every element in the array and perform an action on it. Sometimes you don't actually want to loop through every single item. You may only want to target a specific subset of items. If you do this via map you'd have to perform a conditional check. on each item to see if it passes the requirements necessary to perform the action on them. This can become unruly, hard to understand, and is less efficient (imagine if there are 100,000 items in the array, but only 1000 of them meet the requirements) since you'd have to loop through them all.

Hence the use of filter! By filtering first we are able to create a new array (without affecting the original array, which in many cases is a good thing to avoid doing) that contains only the specific items we need. We can then perform the map function on those specific items without having to loop through the entire array!


Now as for why you got an empty array. It's because when you mapped through each element in the original array you created a new one with a different structure, an array of objects, vs an array of strings: [{name: 'name'}] vs. ['name']. So when you were performing the filter, it was expecting to retrieve a string for it's comparison and got an object instead, thus failing the condition and not adding it to the new filtered array, because this happened to every element in the array (due to the map function you called earlier) it simply failed all the comparisons and thus gave you an empty array since nothing passed the filtering stage.

In the first example with the userNames, you can switch it to do the map first, but keep in mind that when you do that, .map is converting the array of strings to an array of objects, so the filter will have to change to target the name property of the objects, like so:

const users = userNames
    .map(name => ({name}))
    .filter(user => user.name.charAt(0) === 'S');

In the second example, you can't do the filter after the map because you are filtering on the age, and .map is only returning the name from the object, so there is no age to filter on. Remember that when you chain, you are working on the result that is passed from the previous method, not the original input.