JavaScript With Dragons: Learning filter() Method In Depth

Prepare yourself we are going very deep!


Okay, today I’m not going to make you cry to start the tutorial. Let’s see what’s up with our today’s coding plan:

Well you can see where I’m going with this, but don’t worry guys, actually that’s how our ancestors used to make wealth (not mine of course!). They would steal dragon eggs, sell the big ones for Omelette breakfast and the small ones … Well since are not proper for a good Omelette would be sold to potential mother of dragons (or father maybe).

Well, since you ignored the last paragraph I’m going to repeat it here, we are going to steal lots of dragon eggs, pick big ones for Omelette and small ones for Khaleesi, clear? Good. Now before starting to code I’m going to let you watch her for inspirational purposes only.

We are coding to solve problem for people like her, can you see how cool we are? Let’s begin.

Array.prototype.filter()

Filter method is part of the Array prototype and you can use it for all the arrays in your program. The name is kind of self-explanatory, you give it an array and get the array you want in return.

Let’s say we have an array of numbers for the eggs we have already stolen (write the code for stealing yourself), this array is representing the weight of the eggs based on pounds and we are not willing to cook with eggs below five pounds. So we need to separate heavy eggs here.

var eggs = [2,8,3,4,1,3,2,9];
var bigEggs = eggs.filter(function(item) {return item > 5});

Cool! Isn’t it? You can see that this method accepts a callback function which returns a Boolean, if it returns true that specific index value will be saved in the returned array and if the callback returns false or anything that couldn’t be converted as a Truthy value that specific item will be ignored in returned array. In addition, pay attention that filter() does not mutate the main array which it is called. Play around with this code here.

No need to say that we can separate our callback function, for example a filter to separate eggs of odd indexes:

var myFilter = function(item,index) {
if((index % 2) !== 0) // returns true if it's odd
return true
}
var eggs = [2,8,3,4,1,3,2,9];
var bigEggs = eggs.filter(myFilter); // 8,4,3,9

Now you know how we can access to the index of our array, it’s always the second argument in the callback function and it’s totally provided by filter method (same as item). Good! try new things with this code here.

We also have access to the main array with the third argument and it’s useful in some cases when you are executing it on different arrays dynamically.

Since we are planning to go wildly deep today, I’m also going to mention that you can specify an object to be used as this value in your callback. Here, it’s how it’s done:

filter(myCallback[, myThisArg ]);

Brackets means it’s optional and if you ignore it, callback will just use the global object as this. Okay Now what’s the point of it anyway?

Good question! In a working product, you are willing to separate your coding blocks using constructor objects and you may want to separate a large amount of code in a file and use its functionality in other parts of your program. It’s just the way you are using Jquery selectors in your web pages. You write one or two lines of code and you don’t need to worry about all the dirty works executing somewhere hidden in jquery.min.js!

Well, here I believe we can have a good example to understand why we would need to pass this object to filter’s callback. Here, we want to iterate our last program and pick only the heaviest eggs that we have in our basket. We know that we need at least three eggs to make our perfect Omelette, so we need a code to pick the heaviest ones for us:

// You can put this constructor in a separate file
var EggPicker = function() {
// maximum eggs we need
this.MAX_PICK = 3;
// will be used to increment picked eggs
this.picked = 0;

// sort and return based on maximum values
this._sortArray = function(eggsArray) {
return eggsArray.sort().reverse();
}
    // callback function used in filter method
this._myFilterCallback = function(item) {
if (this.picked < this.MAX_PICK) {
this.picked+=1;
return true;
}
}
// our custom filter
this.customFilter = function(eggsArray) {
var sortedEggs = this._sortArray(eggsArray);
return sortedEggs.filter(this._myFilterCallback,this);
}
}
var eggs = [2,8,3,4,1,3,2,9];
var picker = new EggPicker;
var bigEggs = picker.customFilter(eggs); // 9,8,4

Amazing! As you can see, we used a custom filter in our EggPicker object and you can also see an OOP pattern here. We can have multiple instances of our EggPicker object and we are not polluting the global space this way!
Some methods starts with an underscore, this is just a coding convention to define internal methods, it improves the readability since you will know these methods are not going to be used outside of our function scope.

Try this code in action here and try to change it to see how it works. Don’t get into details about this specific solution because it could be solved way easier than how I did, however the point for us is to see how passing this object to filter() is working in bigger projects and it’s just one example of many ways you can benefit from this feature. Try to think and find another application for this pattern in real world programs and send it as a response to this article (or anywhere else).

Just one more thing here !

Yes! Actually in order to make my code simpler I defined my object methods this way:

this.customFilter = function() {}

But better to leave it in a world which Katy Perry is a full-stack developer and use prototypes in the real world where we want to define reusable members like methods.

EggPicker.prototype.customFilter = function() {}

This way we have our method attached to the prototype of the object, so the method is not re-creating every time we create a new instance of our object. That’s enough for here since this article is not about object-oriented approaches in JavaScript, but if you are interested you may find some cool articles out there on the web. Go out and create awesome!

Thanks for staying with me! Don’t forget to give me some feedback please. You can also follow me on Twitter, and maybe say hi or something like that. I tweet some cool things about JavaScript there. Cheers!

Like what you read? Give Pooria Atarzadeh a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.