Last active
June 23, 2018 14:44
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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