Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pass filter options to the Javascript filter method

Tags:

javascript

Suppose a user wants to see a list of musicians based on setting the following booleans:

english_filter = true; // ("EN")
spanish_filter = false; // ("ES")
underground_filter = true; // ("underground")
famous_filter = true; // ("famous")

In the case above, the user chooses to see musicians that speak english and is either famous or underground.

based on these settings, I want to filter an array called customArray.

function applyFilters(el) {
   return el.language === "EN" &&  (el.popularity === 'famous' || el.popularity === 'underground');
}

var filtered = customArray.filter(applyFilters);

this is an example of the "el" structure passed to applyFilters:

{
id: "sHYNYKFENX"
language: "EN"
name: "John Smith"
popularity: "famous"
profile_image:"https://google.com/fakeimage.jpeg"
recording_handle: "DvYenMhJ8Mo"
recording_title: "Awesome song"
}

The code above works, but I'd like to abstract it so that the user can choose whatever combination he wants. How could I create a function to accomplish this?

Thank you so much

UPDATE:

Thanks you for all the answers - I think we are close. Here are some expected results:

var english_filter = false; // ("EN")
var spanish_filter = false; // ("ES")
var underground_filter = false; // ("underground")
var famous_filter = false; // ("famous")

All musicians should be listed.

var english_filter = false; // ("EN")
var spanish_filter = false; // ("ES")
var underground_filter = true; // ("underground")
var famous_filter = false; // ("famous")

Only underground musicians, regardless of what language they speak.


If possible, it'd be great to craft a solution that allows for whatever language you pass it, not just english and spanish. (Not required though). Thank you so much everyone. You are all brilliant.

like image 956
user1683056 Avatar asked Jul 11 '26 08:07

user1683056


1 Answers

I'm guessing you want to use dynamic filters such as:

var filters = { language: "EN" };

// or
var filters = { language: "EN", popularity: "famous" };

// or using an array to indicate more than one option
var filters = {
    language: [
        "EN",
        "ES"
    ],
    popularity: "famous"
};

So, you'd have to write a function to read the options and compare to each objects properties:

function applyFilters(elem, filters) {
    var value, name, objectHasThisProperty, propertyHasValue;
    for(name in filters) {
        value = filters[name];

        objectHasThisProperty = elem.hasOwnProperty(name);
        propertyHasValue = isArray(value) ? inArray(elem[name], value) : elem[name] == value;

        if (!objectHasThisProperty || !propertyHasValue) {
            return false;
        }
    }
    return true;
}

Then you'd call it like this:

var filtered = customArray.filter(function(elem) {
    return applyFilters(elem, filters)
});

Plus the two helper functions:

function isArray(variable) {
    return Object.prototype.toString.call(variable) === '[object Array]';
}
function inArray(needle, haystack) {
    return haystack.indexOf(needle) !== -1;
}

See it in action: JSFiddle.

like image 139
Marcos Dimitrio Avatar answered Jul 13 '26 20:07

Marcos Dimitrio