Reputation: 2543
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
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