我有一个json响应来自一个有点痛苦的服务。如何稍微展平此结构以便"not_restricted":{"doc_count": 976465}
更改为"not_restricted":976465
?我可以使用一个函数来检测所有类型的json文档中的这种结构并修改结果。
这是json的一般结构:
{
"took": 159,
"timed_out": false,
"_shards": {
"total": 6,
"successful": 6,
"failed": 0
},
"hits": {
"total": 4909332,
"max_score": 1,
"hits": [
{
...
},
{
...
},
{
...
}
]
},
"aggregations": {
"index_types": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "client",
"doc_count": 1958205,
"not_restricted": {
"doc_count": 976465
},
"restricted": {
"doc_count": 981740
}
},
{
"key": "ultimateparent",
"doc_count": 1616164,
"not_restricted": {
"doc_count": 741059
},
"restricted": {
"doc_count": 875105
}
},
{
"key": "facility",
"doc_count": 1334963,
"not_restricted": {
"doc_count": 914090
},
"restricted": {
"doc_count": 420872
}
}
]
}
}
}
答案 0 :(得分:5)
您可以使用reviver
parameter of JSON.parse
轻松完成此操作,它允许您过滤JSON中的每个对象:
var res = JSON.parse(json, function(k, o) {
if (Object(o) !== o) return o; // primitive values
var keys = Object.keys(o);
if (keys.length == 1 && keys[0] == "doc_count")
return o.doc_count;
else
return o;
});
如果您想确保仅在此类属性中替换k
单身人士,您还可以测试"restricted"
以包含doc_count
左右。
答案 1 :(得分:1)
您可以使用LoDash让您的生活更轻松。包括它,然后你可以使用_.each
_.each(data.aggregations.index_types.buckets, function(n){
n.not_restricted = n.not_restricted.doc_count;
n.restricted = n.restricted.doc_count;
})
答案 2 :(得分:0)
如果你想通过对象并展平所有1个属性对象,你可以这样做:
for (var i = 0; i < data.aggregations["index_types"].buckets.length; i++) {
var obj = data.aggregations["index_types"].buckets[i];
for (var key in obj) {
if (typeof obj[key] === "object" && Object.keys(obj[key]).length === 1) {
//1 property object!
obj[key] = obj[key][Object.keys(obj[key])[0]];
}
}
}
答案 3 :(得分:0)
由于您说JSON实际上是字符串,如果您需要的只是特定的替换:
Replacing `{"doc_count": NUMBER}` with that `NUMBER`
你可以做的就是用正则表达式替换你想要的东西:
s.replace(/({"doc_count":([0-9]+)})/g, '$2')
其中的作用如下:
( // start capturing group 1
{\"doc_count\": // match the string {\"doc_count\":
( // start capturing group 2
[0-9]+ // match one or more digits
) // close capturing group 2
} // add the rest of the string (a closing bracket)
然后,您可以在$2
中使用replace()
仅提取capturing group 2中的数字。
var json = {
"aggregations": {
"index_types": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [{
"key": "client",
"doc_count": 1958205,
"not_restricted": {
"doc_count": 976465
},
"restricted": {
"doc_count": 981740
}
}, {
"key": "ultimateparent",
"doc_count": 1616164,
"not_restricted": {
"doc_count": 741059
},
"restricted": {
"doc_count": 875105
}
}, {
"key": "facility",
"doc_count": 1334963,
"not_restricted": {
"doc_count": 914090
},
"restricted": {
"doc_count": 420872
}
}]
}
}
};
var s = JSON.stringify(json);
// replace all instances of {doc_count: NUMBER} with that NUMBER
console.log(s.replace(/({"doc_count":([0-9]+)})/g, '$2'));
&#13;
我还注意到您在doc_count
和restricted
之外有属性non_restricted
。如果您只想替换属性restricted
或non_restricted
中的属性,可以使用此正则表达式:
("((?:not_)?restricted"):{"doc_count":([0-9]+)})
在开头添加的部分基本上意味着&#34;从限制&#39;开始。选择&#39;不_&#39;在它之前&#34;
它的使用方式如下:
s.replace(/("((?:not_)?restricted"):{"doc_count":([0-9]+)})/g, '"$2:$3')
var json = {
"aggregations": {
"index_types": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [{
"key": "client",
"doc_count": 1958205,
"not_restricted": {
"doc_count": 976465
},
"restricted": {
"doc_count": 981740
}
}, {
"key": "ultimateparent",
"doc_count": 1616164,
"not_restricted": {
"doc_count": 741059
},
"restricted": {
"doc_count": 875105
}
}, {
"key": "facility",
"doc_count": 1334963,
"not_restricted": {
"doc_count": 914090
},
"restricted": {
"doc_count": 420872
}
}]
}
}
};
var s = JSON.stringify(json);
console.log(s.replace(/("((?:not_)?restricted"):{"doc_count":([0-9]+)})/g, '"$2:$3'));
&#13;
注意:对?:
使用(?:not_)
会使括号中的部分成为非捕获组,因此它不会在捕获组中计算。术语&#34;限制&#34;使用可选的&#34;而不是_&#34;在它现在包含在第2组中之前,数字值在第3组中。我们还需要预先设置"
并将这两个组合并为:
。