Functional programming has been a hot topic as of late.
Map & filter are two crucial functions in functional programming. You don’t have to know anything about functional programming to know how to use them and I guarantee you that these two little functions will improve your code.
Here we have some data containing a list of newly released movies in JSON format:
Each movie has several properties:
bookmark (an array of JSON objects).
In this tutorial, I’m going to solve a simple problem: Collect the IDs of movies with 5.0 ratings.
💓 For the Love of Loops 💓
The first way I will solve this problem makes use of our oldest friend, the humble
Lovely. This gets the job done, but I have three problems with this code:
1) There's a lot of code here to do a simple task. 2) We're making a lot of variables to track our values, which is pretty wasteful memory-wise. 3) Does it really matter that we traverse the movie list from the beginning to end? Couldn't we do it in any order? Do we really *need* to explicitly spell that out in our code?
Ask yourself number three and really sit and contemplate that for a moment. When we use the
for loop to tell an iterator to traverse an array, we have to spell out in code the order in which the array is traversed. This is useful sometimes, but most of the time we’re just going from beginning to end – smells like an opportunity for abstraction to me.
For Each or Not For Each 📖
.forEach() abstracts the explicit logic of the
for loop away. We call
.forEach() on our
newReleases array and trust that the computer will traverse the array. The computer can traverse the array beginning to end, end to beginning, middle out, upside-down, it really doesn’t matter. The point is: we don’t have to tell the computer about how the array is traversed – we just know we’re going to do something on each element of the array. That’s where the iterator function comes in. The iterator function is our instruction to the computer about what should happen when the iterating mechanism (the hidden / implied
for loop) encounters each element in the array. For example, let’s say we want to check if a movie has a rating of 5 stars and push it to a new array called
favorites if it does. Our function would look like this:
By passing this function as an iterator to
.forEach(), we run it on every element in the array.
Unfortunately, the problems I had with the
for loop solution remain with the
1) Still a lot of code for such a simple task. 2) Still using variables to hold values as we go along. 3) We may have gotten rid of the explicit `for` loops, but I still see the word "for" in there. The extra code defining the order of traversal is gone, but we're still saying "for each element in this array, do something." I think the fact that we want to apply this function to each element should be *implied*.
Introducing the 🌟Stars🌟 of the Show
Time to use
.filter() to get the job done. Now that we understand exactly what needs to be done to solve this problem, it should be easy to reverse understand what
.filter() do for us.
.filter() are just unique variations on the classic
.forEach(). The nice thing about them is that they handle a specific case for us so we don’t have to bother telling the computer “for this element, do this”. It just goes without saying that we want each element of the collection to be processed by the reducer function (the same thing as the iterator function in
.filter() is used when we want to *ahem* filter each element in the collection based on a certain condition.
.map() is used when we want to change each element in the array in some way. We’re “mapping” each element from one value to another.
The moment we’ve all been waiting for:
Let’s look at our original pain points and compare:
1) I still think we could do this with less code. 2) Still skeptical about the need for two variables to compute one value... 3) ✔️ No more "for"! I'd say this problem is solved.
Whew, abstracting away that
for loop took some effort, but it’s officially taken care of now. We’re almost done, I promise.
Method chaining is a wonderful thing.
That takes care of number 2.
1) Still a bit verbose. I think we could sweeten this up with some syntactic sugar.* 2) ✔️ One value. One variable. 3) ✔️ No more "for"!
ARROWS ↗️ ⬅️ ⬆️ ➡️ ↘️
Let’s shorten this with some ES6 arrows.
const, & Implicit Return
Proceed with caution. Someone call the fire department. 🚒
1) ✔️ Short & sweet. 2) ✔️ One value. One variable. 3) ✔️ No more "for"!
.filter() the best?
To Learn More:
Here’s the link to the tutorial I got this problem from: http://reactivex.io/learnrx/.