How can I dynamically declare a set of filters criteria without having to specify the number of filters?
For example, if I have a set of data, like this:
var data = [
{ item: { type: 'wood', size: 10 } },
{ item: { type: 'wood', size: 8 } },
{ item: { type: 'metal', size: 8 } }
]
I Know that I can use JS .filter()
to get all of the items that have type
wood
and size
8
:
function filterItems() {
return data.filter(function(val) {
return val['item'].type == 'wood' &&
val['item'].size == 8;
}
}
But what if I want to filter the items with an unknown number of filters, and have .filter()
return all data
items that match those criterion?
Here is a codepen that reflects the above code.
You could pass an array of conditions to the filterItems()
function. Try this:
function filterItems(filters) {
return data.filter(function(val) {
for(var i = 0; i < filters.length; i++)
if(val['item'][filters[i][0]] != filters[i][1])
return false;
return true;
}
}
filterItems([['type', 'wood'], ['size', 8], ['someother', 'value']]);
The same idea can be applied in various formats, such as using objects instead of an array for increased readability.
I just did some one line refactor on Amit's answer for any data structure and nested properties support
// the function
filterItems = (data, filters) => data.filter(item => !filters.find(x => x.key.split('.').reduce((keys, key) => keys[key], item) !== x.value))
// how to use it
filterItems(data, [{ key: 'type', value: 'wood' }, { key: 'some.nested.prop', value: 'value' }])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With