Skip to content

Instantly share code, notes, and snippets.

@ahmed-musallam
Last active June 23, 2018 14:44
Show Gist options
  • Save ahmed-musallam/5b8c4f97b85e76e576203e284c0fb820 to your computer and use it in GitHub Desktop.
Save ahmed-musallam/5b8c4f97b85e76e576203e284c0fb820 to your computer and use it in GitHub Desktop.
A simple method to filter an array of objects based on predicates for strings
/**
* Built this to filters a large array based on predicates to use with a Vuejs app I was building.
* It provides a declarative way to filter an array of objects whose properties are strings.
* But it can be adapted and improved for other types.
* you can see an example vuejs app that uses this method here: http://jsfiddle.net/ahmedmusallam/jruxn3bh/
*/
(function () {
/**
* @param {Arrray} predicates: an array of predicates
* @param {String} operator: either "OR" or "AND". a logical operator for the predicates
*/
Array.prototype.filterWithPredicates = function (predicates, operator) {
// no predicates, return all
if(!predicates) return this;
// determine predicate evaluation operation
operator = operator && operator.toUpperCase() === "OR" ? "some" : "every";
return this.filter(function (item) {
return predicates
// test predicates against array item and return an predicateEvaluation array
.map(function (predicate) {
var value = item[predicate.property];
// item is array, check if atleast one element matches
if (Array.isArray(value)) {
return value.some(function (valueItem) {
return valueItem.indexOf && valueItem.indexOf(predicate.match) > -1;
});
}
// item is not an array but has indexOf (most likely string)
else if (value.indexOf) {
return value.indexOf(predicate.match) > -1;
}
})
// use array some/every depending on operator to determine OR/AND operation
[operator](function (predicateEvaluation) {
return predicateEvaluation === true;
});
});
}
})();
// Usage
var arr = [
{
"id": "5001",
"type": "None",
"description": "nada"
},
{
"id": "5002",
"type": "Glazed",
"description": "meh"
},
{
"id": "5005",
"type": "Sugar",
"description": "it's alright"
},
{
"id": "5007",
"type": "Powdered Sugar",
"description": "better than sugar"
},
{
"id": "5006",
"type": "Chocolate with Sprinkles",
"description": "yes!"
},
{
"id": "5003",
"type": "Chocolate",
"description": "yes! the best"
}
];
var filteredArr = arr.filterWithPredicates([{
property:"type",
match: "Chocolate"
},{
property:"description",
match: "yes"
}]);
// returns
/*
[{
"id": "5007",
"type": "Powdered Sugar",
"description": "better than sugar"
},
{
"id": "5006",
"type": "Chocolate with Sprinkles",
"description": "yes!"
}]
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment