Home > front end >  Filtering an object array with another array
Filtering an object array with another array

Time:02-17

I am having a filtering problem..

objArray is the array that needs to be filtered. selectedNames is an array that contains the values that I want to find in objArray. I need to fetch all objects that have one or more values from selectedNames in their "names" property (an array) .

The output I am trying to get is :

let result = [{names:["A","B","C","D"]},
              {names:["A","B"]},
              {names:["A","D"]}
             ]

Here is a simplified version of my code:

let objArray = [{names:["A","B","C","D"]},
                {names:["C","D"]},
                {names:["C","D","E"]},
                {names:["A","B"]},
                {names:["A","D"]}
               ]

let selectedNames = ["A","B"]

result = this.objArray .filter(obj => {
   return this.selectedNames.includes(obj.names)
}


My code seems to work fine if names attribute was a single value and not an array. But I can't figure out how to make it work on an array.

Any help is more than welcome

CodePudding user response:

You could do something like this. Filtering the array based on the names property having 'some' value be included in the selectedNames array. ...

objArray.filter(obj => obj.names.some(name => selectedNames.includes(name)));

[Edit] As @RadicalTurnip pointed out, this is not performant if the selectedNames is too large. I would suggest that you use an object. E.x

...
const selectedNamesMap = selectedNames.reduce((p,c) => ({...p, [c]: true}), {});
objArray.filter(obj => obj.names.some(name => selelectedNamesMap[name]));

Overkill, but if the arrays are really large (millions of elements) then you are better of using regular for loop and not array methods.

CodePudding user response:

This result is not performant scaled up, but I don't know that there is any way to ensure that it will be performant unless you know more information (like the names are already sorted). That being said, you just missed one more piece of logic.

result = this.objArray.filter(obj => {
  let toReturn = false;
  obj.names.forEach(name => {
    if (this.selectedNames.includes(name))
      toReturn = true;
    };
  };
  return toReturn;
};
  • Related