Javascript () array filter with bind ()

I am using a filter () helper array that goes through some objects in the array. My idea is to create a dynamic filtering function to go through the objects in the array using bind (), but the arguments in bind are used differently than I expected. Here is the code:

var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; // this is the function used in filter() function filterProducts(cat, product){ return product.type === cat; } // new array var vegetables = products.filter(filterProducts.bind(products, "vegetable")); 

I guess that the assistant filter transmits each object in the array after the argument in the method binding, so that at first are products that allow for this in the callback, then this is the type that I want to check each object and, finally, the object itself.

Question: would you recommend to make it so? I mean, if it can be regarded as good practice and it would be better to create a function for each type of filter, instead of doing so?

+5
source share
5 answers

Instead, use the factory:

 var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; function filterProducts(category) { // this is the function used in filter() return function filter(product) { return product.type === category; }; } // new array var vegetables = products.filter(filterProducts("vegetable")); console.log(vegetables); : "vegetable"}, var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; function filterProducts(category) { // this is the function used in filter() return function filter(product) { return product.type === category; }; } // new array var vegetables = products.filter(filterProducts("vegetable")); console.log(vegetables); : "fruit"}, var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; function filterProducts(category) { // this is the function used in filter() return function filter(product) { return product.type === category; }; } // new array var vegetables = products.filter(filterProducts("vegetable")); console.log(vegetables); : "vegetable"}, var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; function filterProducts(category) { // this is the function used in filter() return function filter(product) { return product.type === category; }; } // new array var vegetables = products.filter(filterProducts("vegetable")); console.log(vegetables); () var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; function filterProducts(category) { // this is the function used in filter() return function filter(product) { return product.type === category; }; } // new array var vegetables = products.filter(filterProducts("vegetable")); console.log(vegetables); vegetable")); var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; function filterProducts(category) { // this is the function used in filter() return function filter(product) { return product.type === category; }; } // new array var vegetables = products.filter(filterProducts("vegetable")); console.log(vegetables); 
Run codeHide result

I would recommend this template using bind , because it a little easier to follow, at least in my opinion.

Explanation

If you intend to use filterProducts only as a factory to Array#filter() , then congratulations, you are finished reading this answer. If you complain that the next "icky":

 // product to be validated var product = {name:"lettuce", type:"vegetable"}; // validate that product is a vegetable if (filterProduct('vegetable')(product)) { // code } (product)) { // product to be validated var product = {name:"lettuce", type:"vegetable"}; // validate that product is a vegetable if (filterProduct('vegetable')(product)) { // code } 

Then keep reading.


Functions

Factory are good for determining the class of functions that differ by one or two key variables. In this case, the key variable category . If you want a one-time function that looks beautiful in one line of code, you will find it difficult, if you are not a fan of lodash or something else ... but for this scenario, think about it, instead of the above-mentioned "dowdy" block of code:

 // product to be validated var product = {name:"lettuce", type:"vegetable"}; // vegetable validator var isVegetable = filterProduct('vegetable'); // validate that product is a vegetable if (isVegetable(product)) { // code } ", type: "vegetable"}; // product to be validated var product = {name:"lettuce", type:"vegetable"}; // vegetable validator var isVegetable = filterProduct('vegetable'); // validate that product is a vegetable if (isVegetable(product)) { // code } 

Of course, bind can be good in some situations, and I'm definitely not suggesting you avoid it at all costs, but first you have to ask yourself whether it is really necessary, or simply use before resorting to it.

+5
source

This is really a matter of opinion. Some people use the bind more than others. In designating function arrows es6 post callback binding will be preferred.

Just a note that I would make, is that for clarity when using bind

 var sayName = function(name){ console.log(name) } var sayTony = sayName.bind(null,'Tony') 

It is best to put a null as the first argument, if it is not used within the function.

If you really appreciate the readability, you can be more explicit and declare another function.

 function filterProducts(cat, product){ return product.type === cat; } var filterVegtables = filterProducts.bind(null, 'vegtable'); 

then you can do

 var vegetables = products.filter(filterVegtables); 
+1
source

Are you interested in something like this?

 var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; // this is the function used in filter() function filterProducts(cat){ return this.type === cat[0]; } // new array var veggies = products.filter(function(value){ return filterProducts.bind(value, ['vegetable'])(); }); console.log(veggies); : "vegetable"}, var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; // this is the function used in filter() function filterProducts(cat){ return this.type === cat[0]; } // new array var veggies = products.filter(function(value){ return filterProducts.bind(value, ['vegetable'])(); }); console.log(veggies); : "fruit"}, var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; // this is the function used in filter() function filterProducts(cat){ return this.type === cat[0]; } // new array var veggies = products.filter(function(value){ return filterProducts.bind(value, ['vegetable'])(); }); console.log(veggies); : "vegetable"}, var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; // this is the function used in filter() function filterProducts(cat){ return this.type === cat[0]; } // new array var veggies = products.filter(function(value){ return filterProducts.bind(value, ['vegetable'])(); }); console.log(veggies); ) { var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; // this is the function used in filter() function filterProducts(cat){ return this.type === cat[0]; } // new array var veggies = products.filter(function(value){ return filterProducts.bind(value, ['vegetable'])(); }); console.log(veggies); ']) (); var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; // this is the function used in filter() function filterProducts(cat){ return this.type === cat[0]; } // new array var veggies = products.filter(function(value){ return filterProducts.bind(value, ['vegetable'])(); }); console.log(veggies); 

I still used the bind, but he was more than two liners. Now our value - it (so that each element in the array) and our option (cat) - an array, so I grab it [0].

http://codepen.io/anon/pen/KrBaLB

0
source

Array.filter () method is not magic, it will only iterate the array and call a function for every record. Do not get me wrong - I'm a fan of elegant solutions, but what you're trying to do is nosense. What you do, it (this code is not tested for explanation);

 function filterCondition(obj, arg1, arg2, arg3,.. ) { //TODO: define your individual filter logic } var filter = function(products, arg1, arg2, arg3,.. ) { var filtered = []; for (var i= 0, l = products.length; i < l; i++) { var product = products[i]; if (filterCondition(product, arg1, arg2, arg3,.. )) filtered.push(product); return filtered; } , arg3, ..) { function filterCondition(obj, arg1, arg2, arg3,.. ) { //TODO: define your individual filter logic } var filter = function(products, arg1, arg2, arg3,.. ) { var filtered = []; for (var i= 0, l = products.length; i < l; i++) { var product = products[i]; if (filterCondition(product, arg1, arg2, arg3,.. )) filtered.push(product); return filtered; } , arg2, arg3, ..) { function filterCondition(obj, arg1, arg2, arg3,.. ) { //TODO: define your individual filter logic } var filter = function(products, arg1, arg2, arg3,.. ) { var filtered = []; for (var i= 0, l = products.length; i < l; i++) { var product = products[i]; if (filterCondition(product, arg1, arg2, arg3,.. )) filtered.push(product); return filtered; } ; i ++) { function filterCondition(obj, arg1, arg2, arg3,.. ) { //TODO: define your individual filter logic } var filter = function(products, arg1, arg2, arg3,.. ) { var filtered = []; for (var i= 0, l = products.length; i < l; i++) { var product = products[i]; if (filterCondition(product, arg1, arg2, arg3,.. )) filtered.push(product); return filtered; } arg2, arg3, ..)) function filterCondition(obj, arg1, arg2, arg3,.. ) { //TODO: define your individual filter logic } var filter = function(products, arg1, arg2, arg3,.. ) { var filtered = []; for (var i= 0, l = products.length; i < l; i++) { var product = products[i]; if (filterCondition(product, arg1, arg2, arg3,.. )) filtered.push(product); return filtered; } 

Using bind () is the function in an area that has been identified during the bind .. 1st argument. Therefore, if you need to bind this function, you can use it:

 filter.bind(products, arg1, arg2, arg3,..); 

But this means that the filter function is triggered in the array of products. Therefore, you need to change the settings:

 var filter = function(arg1, arg2, arg3,.. ) { var filtered = []; for (var i= 0, l = this.length; i < l, i++) { var product = this[i]; if (filterCondition(product, arg1, arg2, arg3,.. )) filtered.push(product); return filtered; } , arg3, ..) { var filter = function(arg1, arg2, arg3,.. ) { var filtered = []; for (var i= 0, l = this.length; i < l, i++) { var product = this[i]; if (filterCondition(product, arg1, arg2, arg3,.. )) filtered.push(product); return filtered; } , i ++) { var filter = function(arg1, arg2, arg3,.. ) { var filtered = []; for (var i= 0, l = this.length; i < l, i++) { var product = this[i]; if (filterCondition(product, arg1, arg2, arg3,.. )) filtered.push(product); return filtered; } arg2, arg3, ..)) var filter = function(arg1, arg2, arg3,.. ) { var filtered = []; for (var i= 0, l = this.length; i < l, i++) { var product = this[i]; if (filterCondition(product, arg1, arg2, arg3,.. )) filtered.push(product); return filtered; } 

btw: Jean-Francois used this at the entrance to the array .. it's not, it just looks a bit confusing

0
source

I believe this will give the result you want:

 var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; // this is the function used in filter() function filterProducts(product) { return product.type === this.toString(); } // new array var vegetables = products.filter(filterProducts, "vegetable"); : "vegetable"}, var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; // this is the function used in filter() function filterProducts(product) { return product.type === this.toString(); } // new array var vegetables = products.filter(filterProducts, "vegetable"); () var products = [ {name:"lettuce", type:"vegetable"}, {name:"apple", type:"fruit"}, {name:"carrot", type:"vegetable"}, {name:"orange", type:"fruit"} ]; // this is the function used in filter() function filterProducts(product) { return product.type === this.toString(); } // new array var vegetables = products.filter(filterProducts, "vegetable"); 

but I do not use the function bind.

-1
source

All Articles