Home > OS >  Filter the Array of objects based on another Array Object as condition
Filter the Array of objects based on another Array Object as condition

Time:11-16

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)

  • Related