简体   繁体   中英

Filter the Array of objects based on another Array Object as condition

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 }
]

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)

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;
        }
    });
});

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM