Home > Net >  Checking if an array contains any values from another array?
Checking if an array contains any values from another array?

Time:02-21

I have an array of objects that is structured like so

const tools = [
   {name:"React", image:"react.svg"},
   {name:"Firebase", image:"firebase.svg"},
   {name:"CSS", image:"css.svg"},
]

I then have an array of strings.

const arr = ["React", "Firebase"]

How can I check that the 'tools' array includes all of the filters in the 'arr' array?

I think I am supposed to use the array.every() or the array.some() operator, but i am not sure how to implement either one in this case.

I found this function from a duplicate question, but it doesn't exactly fit my use case as the first array is an array of objects.

let checker = (arr, target) => target.every(v => arr.includes(v));

So my assumption is to loop through the 'tools' array and perform the check that way, but that doesn't seem right logic-wise?

If these were 2 straight up arrays of strings I could do a simple includes() operator and be done.

How do I move on from here? I'm considering pulling the individual name properties out of the array into a proxy array, so then it is two arrays of strings, but I feel like that is much less efficient than doing it with some() or every().

Edit: I am not sure I was clear, but I am checking against the 'name' property in the tools array.

Thank you for any guidance.

CodePudding user response:

You can create a Set from the target array, and then reduce the objects' array (arr) and remove each found item (name in this case) from the accumulator. If the size of the Set is 0, then all targets were found in the array:

const checker = (cb, arr, target) => !arr.reduce((acc, o) => {
  acc.delete(cb(o))
  
  return acc
}, new Set(target)).size

[{"name":"React","image":"react.svg"},{"name":"Firebase","image":"firebase.svg"},{"name":"CSS","image":"css.svg"}]

console.log(checker(o => o.name, tools, ["React", "Firebase"]))

console.log(checker(o => o.name, tools, ["React", "Firebase", "Cats"]))

With TS types (TS Playground):

const checker = <T>(
  cb: (o: any) => T, 
  arr: any[], 
  target: T[]
): boolean => !arr.reduce((acc: Set<T>, o: any) => {
  acc.delete(cb(o))
  
  return acc
}, new Set(target)).size

CodePudding user response:

A very simple solution to this is to use array.prototpye.some() method. It wilkl

const tools = [
   {name:"React", image:"react.svg"},
   {name:"Firebase", image:"firebase.svg"},
   {name:"CSS", image:"css.svg"},
]

const arr = ["React", "Firebase"]

function findCommon(arr1, arr2){ 
 arr1.forEach(obj => {
   const key = Object.values(obj)
    console.log(key.some(item => arr2.includes(item)))
    }
  )
}

findCommon(tools, arr);

CodePudding user response:

I think the simplest solution would be to use .some():

const tools = [
  {name:"React", image:"react.svg"},
  {name:"Firebase", image:"firebase.svg"},
  {name:"CSS", image:"css.svg"},
];

const arr = ["React", "Firebase"]

const result = arr.every((item) => tools.some((tool) => tool.name === item));

console.log(result); // returns true

CodePudding user response:

I'm considering pulling the individual name properties out of the array into a proxy array, so then it is two arrays of strings, but I feel like that is much less efficient than doing it with some() or every().

It's by far the easiest approach.

map over the tools array and get an array of names. Then check to see if the filter array contains all of them.

const tools = [
  {name:'React', image:'react.svg'},
  {name:'Firebase', image:'firebase.svg'},
  {name:'CSS', image:'css.svg'}
];

const arr = ['React', 'Firebase'];
const arr2 = ['React', 'Firebase', 'Steve'];
const arr3 = ['React', 'Firebase', 'CSS'];
const arr4 = ['Firebase'];
const arr5 = ['Steve'];

function contains(tools, arr) {
  const names = tools.map(obj => obj.name);
  return arr.every(el => names.includes(el));
}

console.log(contains(tools, arr));
console.log(contains(tools, arr2));
console.log(contains(tools, arr3));
console.log(contains(tools, arr4));
console.log(contains(tools, arr5));

  • Related