Dynamically group flattened JSON into nested JSON object

Issue

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?

Solution

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);

Answered By – Redu

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published