JavaScript:当路径未知时,检查嵌套对象中是否存在键

时间:2019-05-16 20:20:37

标签: javascript

我正在尝试检查对象中是否存在密钥。

我不知道键可能在哪里或在哪个嵌套对象上,我只知道键的名称(或属性)。对于我来说,拥有一个可以快速搜索对象并确定对象中是否存在属性键的功能非常方便。

为了说明这一点,我的模拟对象将是这样的:

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

我希望找到一个键是否存在的函数将为true"three"的属性键返回"one",并为键返回false"fooBar"

我尝试了hasOwnProperty方法,但是失败了。

2 个答案:

答案 0 :(得分:3)

一种方法是使用像doesObjectHaveNestedKey()这样的递归搜索功能,如下所示(不需要像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

这里的想法是:

  1. 在输入对象“ obj”的键中查找与输入“ key”匹配的键“ k”
  2. 如果找到匹配项,则返回true,否则
  3. 寻找能够存储嵌套对象的“ obj”值“ val”(探索“ Object”类型,因为只有这些对象才能存储嵌套键)和
  4. 递归搜索这些类型的“ val”以查找匹配项,如果找到,则返回true

答案 1 :(得分:3)

Dacre Denny的答案也可以写成:

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