我想在 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]
) 用于排除null
和undefined
第二个(
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/