I'm trying to make a filter. The number of filters will change dynamically, a number of keys can be different, and the number of values, too.
This is how data look like:
var data = [
{id: "123", color: "Red", model: "Tesla"},
{id: "124", color: "Black", model: "Honda"},
{id: "125", color: "Red", model: "Audi"},
{id: "126", color: "Blue", model: "Tesla"}]
Filter keys are color and model. But sometimes I will filter only by color or model and sometimes by both. I want to make a function that will cover both cases. Also, a user can choose many values (Tesla, Honda...).
Key can be only color, or only model, or both. Values can look like: only "Red", "Red" and "Blue", or "Red" and "Tesla", or "Red", "Blue" and "Tesla"... Depends on what user choose.
I tried this:
var filtered = [];
data.forEach(item => {
filterByKey.forEach(key => {
values.forEach(value => {
if (item[key] === value) {
filtered.push(item);
}
});
});
});
Here is JsFiddle
My loop works well when I have one filter key, but it doesn't work well when I have more than one key. Is it a good idea to pass keys and values as an array?
No jQuery please, only pure JavaScript.
You can use filter()
with every()
and check if value of current object with current key exits in values
array using includes()
var data = [{"id":"123","color":"Red","model":"Tesla"},{"id":"124","color":"Black","model":"Honda"},{"id":"125","color":"Red","model":"Audi"},{"id":"126","color":"Blue","model":"Tesla"}]
var keys = ["color", 'model'];
var values = ["Tesla", "Audi", "Red"];
var result = data.filter(function(e) {
return keys.every(function(a) {
return values.includes(e[a])
})
})
console.log(result);
You could use a combined approach with a seach object which keeps the conditions, like
{ model: 'Tesla', // a single value color: ['red', 'blue'], // a some value price: { // a range/interval min: 2000, max: 3000 }, transmission: v => v.toLowerCase() === 'automatic' // a function }
var useConditions = search => a => Object.keys(search).every(k =>
a[k] === search[k] ||
Array.isArray(search[k]) && search[k].includes(a[k]) ||
typeof search[k] === 'object' && +search[k].min <= a[k] && a[k] <= +search[k].max ||
typeof search[k] === 'function' && search[k](a[k])
),
data = [{ id: "123", color: "Red", model: "Tesla" }, { id: "124", color: "Black", model: "Honda" }, { id: "125", color: "Red", model: "Audi" }, { id: "126", color: "Blue", model: "Tesla" }],
filters = { color: ['Red', 'Blue'], model: 'Tesla' };
console.log(data.filter(useConditions(filters)));
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