Home > OS >  Javascript: Filter array of objects based on array values in an efficient way
Javascript: Filter array of objects based on array values in an efficient way

Time:03-06

Let's say I have a data set that looks like below:

const fruits = [
  { fruit: "banana", price: 100 },
  { type: "apple", price: 200 },
  { item: "grape", price: 150 },
  // And so on...
];

const rotten = ["banana", "orange", /* And so on...*/];

I need to filter out elements that contain one of the values in 'rotten' array from 'fruits' array.

Some characteristics:

  1. The key names in the 'fruits' objects are inconsistent. We just know that the corresponding string values are there. I know it is suboptimal but fixing this is sadly not a near-term option.
  2. The actual length of 'fruits' is ~100 and that of 'rotten' is ~10. So this is not a small dataset. (There is a context for saying this...)

I already tried going through each element in 'rotten' and use Object.values(obj).includes() for each element in 'fruits' to eventually create a filtered array, but considering the size of the dataset, this is expensive and I will need a better way to handle this.

What might be a better way to do this? Any suggestions? Thanks a lot in advance!

CodePudding user response:

It is unusual (and not practical) that your input objects all use different properties for storing the same information (fruit, type, item...). So, you should really improve the source of this data.

But given it is like this, you'll have to scan each property of each object and compare it with the rotten fruit names. The latter can be put in a Set, which will reduce the time complexity of the search:

const fruits = [
  { fruit: "banana", price: 100 },
  { type: "apple", price: 200 },
  { item: "grape", price: 150 },
];

const rotten = ["banana", "orange"];

let rottenSet = new Set(rotten);
let result = fruits.filter(item =>
    !Object.values(item).some(value => rottenSet.has(value))
);

console.log(result);

CodePudding user response:

You can try this.

const fruits = [
      { fruit: "banana", price: 100 },
      { type: "apple", price: 200 },
      { item: "grape", price: 150 }
    ];
    
    const rotten = ["banana", "orange"];
    
    const stringfyFruites = JSON.stringify(fruits);
    
    let filterdArray = [];
    rotten.forEach((value) => {
      const regexstr = '{[\\w":,\\s] '   value   '[\\w":,\\s] }';
      const matchedobject = stringfyFruites
        .match(new RegExp(regexstr, "gm"))
        ?.map((a) => JSON.parse(a));
      if (matchedobject?.length) filterdArray = [...filterdArray, ...matchedobject];
    });
  • Related