如何从嵌套对象中获取所有具有值的键

新手上路,请多包涵

我正在寻找类似 Object.keys 的东西,但它适用于潜在的嵌套对象。它也不应该包括具有对象/数组值的键(它应该只包括具有直接字符串/数字/布尔值的键)。

例一

输入

{
   "check_id":12345,
   "check_name":"Name of HTTP check",
   "check_type":"HTTP"
}

预期产出

[
  "check_id",
  "check_name",
  "check_type"
]

Object.keys 适用于这样的平面案例,但不适用于嵌套案例:

例子二

输入

{
   "check_id":12345,
   "check_name":"Name of HTTP check",
   "check_type":"HTTP",
   "tags":[
     "example_tag"
   ],
   "check_params":{
      "basic_auth":false,
      "params":[
        "size"
      ],
      "encryption": {
        "enabled": true,
      }
   }
}

预期产出

[
  "check_id",
  "check_name",
  "check_type",
  "check_params.basic_auth",
  "check_params.encryption.enabled"
]

Note that this does not include tags , check_params , check_params.params , or check_params.encryption since these values are arrays/objects.

问题

有做这个的图书馆吗?您将如何实现它以便它可以处理任何对象,无论是大对象还是嵌套对象?

原文由 user3773571 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 483
2 个回答

你可以像这样使用 reduce :

 const keyify = (obj, prefix = '') =>
  Object.keys(obj).reduce((res, el) => {
    if( Array.isArray(obj[el]) ) {
      return res;
    } else if( typeof obj[el] === 'object' && obj[el] !== null ) {
      return [...res, ...keyify(obj[el], prefix + el + '.')];
    }
    return [...res, prefix + el];
  }, []);

const input = {
   "check_id":12345,
   "check_name":"Name of HTTP check",
   "check_type":"HTTP",
   "tags":[
     "example_tag"
   ],
   "check_params":{
      "basic_auth":false,
      "params":[
        "size"
      ],
      "encryption": {
        "enabled": true,
        "testNull": null,
      }
   }
};

const output = keyify(input);

console.log(output);

Edit1: 对于您想要包含数组的一般情况。

 const keyify = (obj, prefix = '') =>
  Object.keys(obj).reduce((res, el) => {
    if( typeof obj[el] === 'object' && obj[el] !== null ) {
      return [...res, ...keyify(obj[el], prefix + el + '.')];
    }
    return [...res, prefix + el];
  }, []);

const input = {
   "check_id":12345,
   "check_name":"Name of HTTP check",
   "check_type":"HTTP",
   "tags":[
     "example_tag"
   ],
   "nested": [
      { "foo": 0 },
      { "bar": 1 }
   ],
   "check_params":{
      "basic_auth":false,
      "params":[
        "size"
      ],
      "encryption": {
        "enabled": true,
        "testNull": null,
      }
   }
};

const output = keyify(input);

console.log(output);

原文由 Olian04 发布,翻译遵循 CC BY-SA 4.0 许可协议

生成器可以快速解决此类问题 -

 function* deepKeys (t, pre = [])
{ if (Array.isArray(t))
    return
  else if (Object(t) === t)
    for (const [k, v] of Object.entries(t))
      yield* deepKeys(v, [...pre, k])
  else
    yield pre.join(".")
}

const input =
  {check_id:12345,check_name:"Name of HTTP check",check_type:"HTTP",tags:["example_tag"],check_params:{basic_auth:false,params:["size"],encryption:{enabled:true,testNull:null,}}}

console.log(Array.from(deepKeys(input)))
 [ "check_id"
, "check_name"
, "check_type"
, "check_params.basic_auth"
, "check_params.encryption.enabled"
, "check_params.encryption.testNull"
]


或者急切地计算所有键的纯函数表达式 -

 const deepKeys = (t, pre = []) =>
  Array.isArray(t)
    ? []
: Object(t) === t
   ? Object
      .entries(t)
      .flatMap(([k, v]) => deepKeys(v, [...pre, k]))
: pre.join(".")

const input =
  {check_id:12345,check_name:"Name of HTTP check",check_type:"HTTP",tags:["example_tag"],check_params:{basic_auth:false,params:["size"],encryption:{enabled:true,testNull:null,}}}

console.log(deepKeys(input))
 [ "check_id"
, "check_name"
, "check_type"
, "check_params.basic_auth"
, "check_params.encryption.enabled"
, "check_params.encryption.testNull"
]

原文由 Mulan 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题