I have this array of objects
const data = [
{ id: 0, ALT_VALUE: 11, DLT_VALUE: 76 },
{ id: 1, ALT_VALUE: 80, DLT_VALUE: 48 },
{ id: 2, ALT_VALUE: 90, DLT_VALUE: 100 },
{ id: 3, ALT_VALUE: 12, DLT_VALUE: 70 },
{ id: 4, ALT_VALUE: 90, DLT_VALUE: 100 },
{ id: 5, ALT_VALUE: 13, DLT_VALUE: 49 },
{ id: 6, ALT_VALUE: 76, DLT_VALUE: 70 },
{ id: 7, ALT_VALUE: 9, DLT_VALUE: 15 },
];
and I would like to filter it dynamically based on this array of objects
const filters = [
{ parameter: "ALT_VALUE", min: 8, max: 100 },
{ parameter: "DLT_VALUE", min: 30, max: 50 },
];
based on the filters, the final result supposed to be
[
{ id: 5, ALT_VALUE: 13, DLT_VALUE: 49 },
{ id: 1, ALT_VALUE: 80, DLT_VALUE: 48 },
]
I tried with this
const result = data.filter((el) => {
return filters.filter((f) => {
if (el[f.parameter] > f.min && el[f.parameter] < f.max) {
return el;
}
});
});
But I get all of the data
[
{ id: 0, ALT_VALUE: 11, DLT_VALUE: 76 },
{ id: 1, ALT_VALUE: 80, DLT_VALUE: 48 },
{ id: 2, ALT_VALUE: 90, DLT_VALUE: 100 },
{ id: 3, ALT_VALUE: 12, DLT_VALUE: 70 },
{ id: 4, ALT_VALUE: 90, DLT_VALUE: 100 },
{ id: 5, ALT_VALUE: 13, DLT_VALUE: 49 },
{ id: 6, ALT_VALUE: 76, DLT_VALUE: 70 },
{ id: 7, ALT_VALUE: 9, DLT_VALUE: 15 }
]
CodePudding user response:
Since you want all the filters to be respected you need to use every instead of filter.
If you use filter if any of filter rule is match it will result in adding that to final output.
const data = [
{ id: 0, ALT_VALUE: 11, DLT_VALUE: 76 },
{ id: 1, ALT_VALUE: 80, DLT_VALUE: 48 },
{ id: 2, ALT_VALUE: 90, DLT_VALUE: 100 },
{ id: 3, ALT_VALUE: 12, DLT_VALUE: 70 },
{ id: 4, ALT_VALUE: 90, DLT_VALUE: 100 },
{ id: 5, ALT_VALUE: 13, DLT_VALUE: 49 },
{ id: 6, ALT_VALUE: 76, DLT_VALUE: 70 },
{ id: 7, ALT_VALUE: 9, DLT_VALUE: 15 },
];
const filters = [
{ parameter: "ALT_VALUE", min: 8, max: 100 },
{ parameter: "DLT_VALUE", min: 30, max: 50 },
];
const result = data.filter((el) => {
return filters.every((f) => {
if (el[f.parameter] > f.min && el[f.parameter] < f.max) {
return el;
}
});
})
console.log(result)
CodePudding user response:
In your function, filters.filter()
returns an Array
, which JavaScript sees as a truthy value. This means that every item in data
passes your filter (each iteration yields an array, empty or not, which is interpreted as true
), and everything is included.
By having your filter
return a Boolean value instead, you can avoid JavaScript coercing an Array to a Boolean value:
const result = data.filter((el) => {
// every will only return true if all filters match,
// else it will return false
return filters.every((f) => {
if (el[f.parameter] > f.min && el[f.parameter] < f.max) {
return el;
}
});
});
CodePudding user response:
Please use every
instead of second filter
Array.prototype.every
will return true if every element in the array matches your condition in the callback
const data = [
{ id: 0, ALT_VALUE: 11, DLT_VALUE: 76 },
{ id: 1, ALT_VALUE: 80, DLT_VALUE: 48 },
{ id: 2, ALT_VALUE: 90, DLT_VALUE: 100 },
{ id: 3, ALT_VALUE: 12, DLT_VALUE: 70 },
{ id: 4, ALT_VALUE: 90, DLT_VALUE: 100 },
{ id: 5, ALT_VALUE: 13, DLT_VALUE: 49 },
{ id: 6, ALT_VALUE: 76, DLT_VALUE: 70 },
{ id: 7, ALT_VALUE: 9, DLT_VALUE: 15 },
];
const filters = [
{ parameter: "ALT_VALUE", min: 8, max: 100 },
{ parameter: "DLT_VALUE", min: 30, max: 50 },
];
const result = data.filter((el) => {
return filters.every((f) => {
if (el[f.parameter] > f.min && el[f.parameter] < f.max) {
return el;
}
});
});
console.log(result)