Skip to content
Advertisement

Dynamically group flattened JSON into nested JSON object

Suppose I have the following JSON array:

[
    {
        "MainCategory": "1",
        "SubCategory": "a",
        "Value": "val1"
    },
    {
        "MainCategory": "1",
        "SubCategory": "a",
        "Value": "val2"
    },
    {
        "MainCategory": "1",
        "SubCategory": "b",
        "Value": "val3"
    },
    {
        "MainCategory": "2",
        "SubCategory": "a",
        "Value": "val4"
    },
    {
        "MainCategory": "2",
        "SubCategory": "b",
        "Value": "val5"
    },
    {
        "MainCategory": "2",
        "SubCategory": "b",
        "Value": "val6"
    }
]

And would like to convert it into the following multidimensional object in JavaScript (no Lodash):

{
    "1":{
        "a": [
            "val1",
            "val2"
        ],
        "b": [
            "val3"
        ]
    },
    "2":{
        "a": [
            "val4"
        ],
        "b": [
            "val5",
            "val6"
        ]
    }
}

I figure I can do it with a foreach, but I’m trying to do it using the reduce function (HOPING that is the right one to use here) and just not getting the right syntax.

My current GUESS (not working) is something along the lines of:

const newJson = CurrentJson.reduce((result, {MainCategory, SubCategory, Value}) => {
    (result[MainCategory][SubCategory] = result[MainCategory][SubCategory] || [])
    .push(Value);

    return result;
}, {});

How can I do this?

Answer

You may use reduce as follows;

var data = [ { "MainCategory": "1"
             , "SubCategory": "a"
             , "Value": "val1"
             }
           , { "MainCategory": "1"
             , "SubCategory": "a"
             , "Value": "val2"
             }
           , { "MainCategory": "1"
             , "SubCategory": "b"
             , "Value": "val3"
             }
           , { "MainCategory": "2"
             , "SubCategory": "a"
             , "Value": "val4"
             }
           , { "MainCategory": "2"
             , "SubCategory": "b"
             , "Value": "val5"
             }
           , { "MainCategory": "2"
             , "SubCategory": "b"
             , "Value": "val6"
             }
           ],
   res  = data.reduce((r,o) => ( r[o.MainCategory] ? r[o.MainCategory][o.SubCategory] ? r[o.MainCategory][o.SubCategory].push(o.Value)
                                                                                      : r[o.MainCategory][o.SubCategory] = [o.Value]
                                                   : r[o.MainCategory] = {[o.SubCategory]: [o.Value]}
                               , r
                               ) ,{});
  console.log(res);
Advertisement