0

I'm wondering if there is any implimentation of a object.contains method in javascript that works similar to how the Python version object.__contains__() works, as in I want to be able to scan the whole object with nested objects to see if there is either a key or a value that does contain what the method is comparing it against. I know there are other ways in Javascript to do this such as using filter and some, but they don't work for me.

person: {
  name: 'Bob',
  age: 40,
  items: {
    cars: 4,
    house: 1,
    computer: 2
  }
}

I need something that scans the WHOLE object rather than just the first level of it (which would be name, age, and items, and if you searched for cars you wouldn't get any response).

crypthusiast0
  • 407
  • 2
  • 4
  • 19
  • Not an expert in python, but [`__contains__`](https://docs.python.org/2/reference/datamodel.html#object.__contains__) states "For mapping objects, this should consider the keys of the mapping rather than the values or the key-item pairs." so what you describe is actually not the behavior of contains right? – Jonas Wilms Jul 14 '21 at 15:31
  • not actually sure, I just saw a friend use it in a similar application and assumed the way he did it was the correct way since he's a much more experienced coder than I am.. – crypthusiast0 Jul 14 '21 at 15:43

2 Answers2

2

I don't think so. A naive take would be

JSON.stringify(target).includes( JSON.stringify( search ) )

It doesn't work well if search is not a string though, as that will also match also inside strings. A non naive approach would be something like this:

const contains = (obj, search) => 
 Object.keys(obj).includes(search) ||
 Object.values(obj).includes(search) ||
 Object.values(obj)
   .filter(it => typeof it === "object" && it !== null)
   .some(it => contains(it, search));
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
1

Do not have a standard function for this i guess but you can for sure write a custom recursive function using some typeof and Object.entries().

let person =  {
  name: 'Bob',
  age: 40,
  items: {
    cars: 4,
    house: 1,
    computer: 2
  }
};

function searchForTerm(obj,item){
  
  for(let [key,val] of Object.entries(obj)){
    if(key == item){
      return true;
    }
    else if(typeof val === 'object')  
     {
       if(searchForTerm(val,item)){
         return true;
       }
     }
    else if(val == item){
      return true;
    }
  }
  return false;
}

console.log(searchForTerm(person,40));
console.log(searchForTerm(person,43));
console.log(searchForTerm(person,'Bob'));
console.log(searchForTerm(person,'cars'));
console.log(searchForTerm(person,'truck'));

I am using == in first case, so type checking is not done.

Obviously, this is a starter and you can modify based on your needs. But this should get you going.

Tushar Shahi
  • 16,452
  • 1
  • 18
  • 39