0

I'm trying to use an if (key in object) statement to get if a key exists in an object, however I've noticed that it only works for the first level of an object, like this:

myObject = {
  name: 'Bob',
  age: 20,
  dog: true
}

However, it doesn't seem to work with nested objects like this:

myObject = {
  name: 'Joe',
  favorites: {
    ice_cream: 'vanilla',
    coffee: 'espresso'
  }
}

If I were to run console.log('coffee' in myObject), it would return false. I've also tried using myObject.hasOwnProperty('coffee'), however it still returns false.

crypthusiast0
  • 407
  • 2
  • 4
  • 19
  • Does this answer your question? [Test for existence of nested JavaScript object key](https://stackoverflow.com/questions/2631001/test-for-existence-of-nested-javascript-object-key) – Rajesh Paudel Jun 01 '21 at 05:34

2 Answers2

1

If you really want to be able to check if the key exists anywhere inside the object recursively, you'll need a recursive function.

const myObject = {
  name: 'Joe',
  favorites: {
    ice_cream: 'vanilla',
    coffee: 'espresso'
  }
};

const getKeys = (obj, keys = [], visited = new Set()) => {
  if (visited.has(obj)) return;
  visited.add(obj);
  keys.push(...Object.keys(obj));
  for (const val of Object.values(obj)) {
    if (val && typeof val === 'object') {
      getKeys(val, keys, visited);
    }
  }
  return keys;
};
console.log(getKeys(myObject));
console.log(getKeys(myObject).includes('coffee'));

But while this is possible, it's really weird. I would hope never to see anything like this in serious code.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • What do you think the best approach is for checking if a key exists? I'm working with a pretty big object which is an item's decoded NBT from Minecraft, and different items have different fields, so I can't just write the same thing that works for every item. – crypthusiast0 Jun 01 '21 at 05:42
  • Figure out what the object's structure can be like in advance so you can go right to the possible property you want to find. This may involve array or object methods - that's fine - but iterating over the *whole object* all the way down is a mark of not knowing enough about your input. – CertainPerformance Jun 01 '21 at 05:44
0

You can try this,

function getKey(obj) {
    let objectKeys = [];
    let keyValues = Object.entries(obj);
    for (let i in keyValues) {
        objectKeys.push(keyValues[i][0]);
        if (typeof keyValues[i][1] == "object") {
            var keys = getKey(keyValues[i][1])
            objectKeys = objectKeys.concat(keys);
        }
    }
    return objectKeys;
}

You can pass the key to the function and check,

 let key = getKey(coffee);
 console.log(key);
RGA
  • 303
  • 3
  • 11