Horse Voice Horse Voice - 1 month ago 11
Javascript Question

Flatten a json datastructure in javascript

I have a json response coming from a service that's a bit of a pain to work with. How can I go about flattening this structure a bit so that

"not_restricted":{"doc_count": 976465}
is changed to
"not_restricted":976465
? I'd perfer a function that can detect this kind of a structure in all types of json docs and modify the result.

This is a the general structure of the 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
}
}
]
}
}
}

Answer

You can very easily do this by using the reviver parameter of JSON.parse, which allows you to filter every object in the 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;
});

You can also test k to include "restricted" or so if you want to make sure that doc_count singletons are only replaced in such properties.