最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

JavaScript: Check for existence of key in nested objects when its path is unknown - Stack Overflow

programmeradmin1浏览0评论

I'm trying to check if a key exists in my object.

I don't know where or on which nested object the key could be specifically, I just know the name of the key (or property). It would be very handy for me to have a function allowing to quickly search the object and determine if the property key exists in the object.

To illustrate this, my mock object would be something like this:

const testObject = {
  one : {
    two : {
      three : "hello"
    }
  }
}

I would expect that a function to find if a key exists would return true for a property key of "three" or "one", and would return false for a key of "fooBar"

I have tried the hasOwnProperty method but it fails.

I'm trying to check if a key exists in my object.

I don't know where or on which nested object the key could be specifically, I just know the name of the key (or property). It would be very handy for me to have a function allowing to quickly search the object and determine if the property key exists in the object.

To illustrate this, my mock object would be something like this:

const testObject = {
  one : {
    two : {
      three : "hello"
    }
  }
}

I would expect that a function to find if a key exists would return true for a property key of "three" or "one", and would return false for a key of "fooBar"

I have tried the hasOwnProperty method but it fails.

Share Improve this question edited May 16, 2019 at 21:57 Dacre Denny 30.4k5 gold badges51 silver badges66 bronze badges asked May 16, 2019 at 20:20 Diagathe JosuéDiagathe Josué 12.2k14 gold badges49 silver badges93 bronze badges 2
  • If you don't need the value, a simple JSON.stringify(nestedObjects).indexOf('"thePropName":') !== -1 would probably work. – Emile Bergeron Commented May 16, 2019 at 20:29
  • Note that JSON.stringify will remove the key if its value isn't serializable, like a Function. – Emile Bergeron Commented May 16, 2019 at 20:51
Add a ment  | 

3 Answers 3

Reset to default 4

One approach would be with a recursive search function like doesObjectHaveNestedKey() as shown below ( which this does not require an extra dependency like lodash ):

const object = {
  some : {
    nested : {
      property : {
        to : [
          {
            find : {
              foo : [ 1 , 2 , 3 ]
            }
          }
        ]
      }
    }
  }
}

/* Define function to recursively search for existence of key in obj */
function doesObjectHaveNestedKey(obj, key) {

  if(obj === null || obj === undefined) {
    return false;
  }
  
  for(const k of Object.keys(obj)) {
  
    if(k === key) {
      /* Search keys of obj for match and return true if match found */
      return true
    }
    else {
      const val = obj[k];
      
      /* If k not a match, try to search it's value. We can search through
      object value types, seeing they are capable of containing
      objects with keys that might be a match */
      if(typeof val === 'object') {
      
        /* Recursivly search for nested key match in nested val */
        if(doesObjectHaveNestedKey(val, key) === true) {
          return true;
        }
      }
    }
  }
  
  return false;
}

console.log('has foo?', doesObjectHaveNestedKey(object, 'foo') )        // True
console.log('has bar?', doesObjectHaveNestedKey(object, 'bar') )        // False
console.log('has nested?', doesObjectHaveNestedKey(object, 'nested') )  // True
console.log('has cat?', doesObjectHaveNestedKey(null, 'cat') )          // False

The idea here is to:

  1. look through the keys of the input object "obj" for a key "k" that matches the input "key"
  2. if a match is found return true, otherwise
  3. look for any value "val" of "obj" that is able to store nested objects (Explore "Object" types as only these can store nested keys) and
  4. recursively search a "val" of those types for a match and if found, return true

The answer of Dacre Denny could also be written as:

  const hasKey = (obj, key) => 
    Object.keys(obj).includes(key) ||
    Object.values(obj)
      .filter(it => typeof it === "object" && it !== null)
      .some(it => hasKey(it, key));

Another recursive function. If the current obj is an object, look if its keys includes the target key. If isn't included, recall the function for each obj value:

const searchKey = (obj, key) => 
    obj && typeof obj === "object" &&
    (Object.keys(obj).includes(key) ||
    Object.values(obj).some(o => searchKey(o, key)));

Try the snippet

const testObject = {
  one: {
    two: {
      three: "hello"
    }
  },
  foo: {
    bar: {
      foobar: 10
    }
  }
}

const searchKey = (obj, key) => 
    obj && typeof obj === "object" &&
    (Object.keys(obj).includes(key) ||
    Object.values(obj).some(o => searchKey(o, key)));


console.log(searchKey(testObject, "two")); //true
console.log(searchKey(testObject, "foo")); //true
console.log(searchKey(testObject, "barfoo")); //false
console.log(searchKey(testObject, "foobar")); //true

发布评论

评论列表(0)

  1. 暂无评论