jose
jose

Reputation: 2543

filter javascript object

I have a javascript object, that could be something like this

{
    "users": [{
        "id": "52",
        "name": "User name one",
        "profile": "student",
        "statusId": 1
    },...

I want to modify this object's properties given a set of parameters. Basically I want a new object which properties could match a set of constraints - a filter object - with this form (empty filter):

    var userFilter = {
        id : "",
        name: "",
        profile : "",
        state : ""
    };

I've seen the Array.prototype.filter, but can't figure a clean and generic way to use all properties of filter. I've tried this approach with a javascript string that concats all filters and using eval(), but I don't like this approach. Any suggestion ?

Thanks in advance, regards

Upvotes: 0

Views: 3375

Answers (1)

georg
georg

Reputation: 214949

You can use something like this to compare two Javascript objects:

// returns true if "obj" contains "other" as a subset
contains = function(obj, other) {
    return Object.keys(other).every(function(key) {
        return other[key] == obj[key];
    });
}

for example, contains(users[0], {profile: 'student'} ) returns true.

Once we have this, the rest is easy:

 userFilter = { ...criteria... }
 results = users.filter(function(item) { return contains(item, userFilter) })

Note that this does AND matching, that is, if the filter is {state:5, profile:'student'}, it finds records that have both state=5 and profile=student. To do OR matching instead, replace every() with some() in the above code.

As per your comment, the above function can be generalized by adding a comparison function as a parameter:

contains = function(obj, other, compare) {
    return Object.keys(other).every(function(key) {
        return compare ? compare(key, obj[key], other[key]) 
            : obj[key] == other[key];
    });
}

Comparison function accepts key, object value and filter value and is supposed to return true or false. Example:

user =  {
       "id": "52",
       "name": "Foo Bar"
}

// this uses the default "equals" comparison and fails
contains(user, { name: "Foo" });

// this uses a custom "indexOf" comparison and succeeds 
contains(user, { name: "Foo" }, function(key, val, flt) {
    return val.indexOf(flt) >= 0;
});

Upvotes: 2

Related Questions