javascript - js中如何通过key搜索多层嵌套对象

标签 javascript lodash

我想在 JavaScript 中搜索多层嵌套对象。层数是动态的,不是固定的。 假设我有一个这样的对象。

       data={
            "_index": "sample_data_logs",
            "_type": "_doc",
            "_id": "lDMTgnEBbYNxp5GHN-gj",
            "_version": 1,
            "_score": 7.6343846,
            "_source": {
                "agent": "Mozilla/4.0",
                "bytes": 6948,
                "clientip": "172.3.128.226",
                "extension": "",
                "geo": {
                    "srcdest": "IN:BY",
                    "src": "IN",
                    "dest": "BY",
                    "coordinates": {
                        "lat": 41.92076333,
                        "lon": -71.49138139
                    }
                },
                "host": "www.host.co",
                "index": "sample_data_logs",
                "ip": "172.3.128.226",
                "machine": {
                    "ram": 5368709120,
                    "os": "win 8"
                },
                "memory": null,
                "phpmemory": null,
                "request": "/apm",
                "response": 200,
                "tags": [
                    "success",
                    "security"
                ],
                "timestamp": "2020-04-13T11:05:05.551Z",
                "url": "https://www.elastic.co/downloads/apm",
                "utc_time": "2020-04-13T11:05:05.551Z"
            }
        }
       keys= ["_index","bytes","os","tags"];

我有一个键值数组可以在数据中查找或过滤。
我怎样才能做到这一点? 我尝试过使用lodash

_.pick(data_, keys);

我没有得到预期的结果:

                   {
                    "_index": "sample_data_logs",
                    "bytes": 6948,
                    "os": "win 8",
                    "tags": [
                      "success",
                      "security"
                     ]
                    }

执行此操作的最佳方法是什么?可以在 vanilla js 中完成吗?

最佳答案

您需要递归地遍历数据,如下所示:

说明:

我们有一个函数traverse,它需要:

  • 一个对象(称为数据),
  • 键列表(称为keys),
  • 以及一个包含当前结果的对象(找到的键/值对称为结果)

traverse函数中,我们检查对象数据的第一级键(使用Object.keys(data))并检查它们是否在keys 列表,如果是,则我们将该键/值对添加到结果中并转到下一个。

但是如果它不在中,那么我们需要检查该键是否是嵌套对象,因此我们按照以下条件执行此操作:

if (
  data[k] &&
  typeof data[k] === "object" &&
  Object.keys(data[k]).length > 0
)
  • 第一个 (data[k]) 用于排除 nullundefined

    <
  • 第二个(typeof data[k] === "object")用于检查值是否是对象

  • 第三个条件用于排除像 Date 这样的原生对象

如果它是一个嵌套对象,那么我们再次调用遍历(递归)

let data = {
  _index: "sample_data_logs",
  _type: "_doc",
  _id: "lDMTgnEBbYNxp5GHN-gj",
  _version: 1,
  _score: 7.6343846,
  _source: {
    agent: "Mozilla/4.0",
    bytes: 6948,
    clientip: "172.3.128.226",
    extension: "",
    geo: {
      srcdest: "IN:BY",
      src: "IN",
      dest: "BY",
      coordinates: {
        lat: 41.92076333,
        lon: -71.49138139,
      },
    },
    host: "www.host.co",
    index: "sample_data_logs",
    ip: "172.3.128.226",
    machine: {
      ram: 5368709120,
      os: "win 8",
    },
    memory: null,
    phpmemory: null,
    request: "/apm",
    response: 200,
    tags: ["success", "security"],
    timestamp: "2020-04-13T11:05:05.551Z",
    url: "https://www.elastic.co/downloads/apm",
    utc_time: "2020-04-13T11:05:05.551Z",
  },
};
let keys = ["_index", "bytes", "os", "tags"];

function traverse(data, keys, result = {}) {
  for (let k of Object.keys(data)) {
    if (keys.includes(k)) {
      result = Object.assign({}, result, {
        [k]: data[k]
      });
      continue;
    }
    if (
      data[k] &&
      typeof data[k] === "object" &&
      Object.keys(data[k]).length > 0
    )
      result = traverse(data[k], keys, result);
  }
  return result;
}

result = traverse(data, keys);
console.log(result);

关于javascript - js中如何通过key搜索多层嵌套对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61520358/

相关文章:

javascript - 使用 lodash 在对象数组中展平数组

javascript - 使用 lodash、下划线或数组函数的多级/多级组

javascript - 如何创建一个简单的启动画面/页面?

javascript - 使用键码在可滚动的 div 中上下导航

javascript - AngularJS 嵌套 ng-repeat

javascript - 我可以使用另一个 _.get 作为 lodash _.get 的默认值吗?

javascript - TypeScript 中的深度克隆(保留类型)

javascript - 触发按钮时从数据表中的行获取下拉选定值

javascript - 使用嵌套映射的 JSON 对象反序列化,Java Spring

javascript - 使用 lodash 进行数据操作(某种左连接)