-2

Here is the format of the JSON output i get

oldJSON = [
{ "Node": "Node1", "NodeParent": "" },
{ "Node": "Node1A", "NodeParent": "Node1" },
{ "Node": "Node1B", "NodeParent": "Node1" },
{ "Node": "Node2", "NodeParent": "" },
{ "Node": "Node2A", "NodeParent": "Node2" },
{ "Node": "Node2B", "NodeParent": "Node2" },
{ "Node": "Node3", "NodeParent": "" },
{ "Node": "Node3A", "NodeParent": "Node3" },
{ "Node": "Node3A1", "NodeParent": "Node3;Node3A" },
{ "Node": "Node3A2", "NodeParent": "Node3;Node3A" },
{ "Node": "Node3A3", "NodeParent": "Node3;Node3A" },
{ "Node": "Node3A1x", "NodeParent": "Node3;Node3A:Node3A1" },
{ "Node": "Node3A1y", "NodeParent": "Node3;Node3A:Node3A1" },
{ "Node": "Node3A1z", "NodeParent": "Node3;Node3A:Node3A1" },
{ "Node": "Node3B", "NodeParent": "Node3" },
{ "Node": "Node3B1", "NodeParent": "Node3;Node3B" },
{ "Node": "Node3B2", "NodeParent": "Node3;Node3B" },
{ "Node": "Node3B3", "NodeParent": "Node3;Node3B" },
{ "Node": "Node3B1x", "NodeParent": "Node3;Node3B:Node3B1" },
{ "Node": "Node3B1y", "NodeParent": "Node3;Node3B:Node3B1" },
{ "Node": "Node3B1z", "NodeParent": "Node3;Node3B:Node3B1" }]

I would like convert this above JSON to tree like structure as shown below.

NewJsonArray = [
{
    "Node": "Node1",
    "children": [
        {
            "Node": "Node1A"
        },
        {
            "Node": "Node1B"
        }
    ]
},
{
    "Node": "Node2",
    "children": [
        {
            "Node": "Node2A"
        },
        {
            "Node": "Node2B"
        }
    ]
},
{
    "Node": "Node3",
    "children": [
        {
            "Node": "Node3A"
        },
        {
            "Node": "Node3B"
        }
    ],
    "Node3A": {
        "Node": "Node3A",
        "children": [
            {
                "Node": "Node3A1"
            },
            {
                "Node": "Node3A2"
            },
            {
                "Node": "Node3A3"
            }
        ],
        "Node3A1": {
            "Node": "Node3A1",
            "children": [
                {
                    "Node": "Node3A1x"
                },
                {
                    "Node": "Node3A1y"
                },
                {
                    "Node": "Node3A1z"
                }
            ]
        }
    },
    "Node3B": {
        "Node": "Node3B",
        "children": [
            {
                "Node": "Node3B1"
            },
            {
                "Node": "Node3B2"
            },
            {
                "Node": "Node3B3"
            }
        ],
        "Node3B1": {
            "Node": "Node3B1",
            "children": [
                {
                    "Node": "Node3B1x"
                },
                {
                    "Node": "Node3B1y"
                },
                {
                    "Node": "Node3B1z"
                }
            ]
        }
    }
}

]

As you can notice the NodeParent is separated by semicolon, the requirement is to split the NodeParent so that the tree like JSON can be generated and pushed under corresponding parent nodes.

  • does `NodeParent` contains always the whole path to the node? please add your try. – Nina Scholz Nov 22 '18 at 17:37
  • 3
    That's not [JSON](http://json.org) but an array of objects -> [What is the difference between JSON and Object Literal Notation?](https://stackoverflow.com/questions/2904131/what-is-the-difference-between-json-and-object-literal-notation) – Andreas Nov 22 '18 at 17:39
  • @NinaScholz, Yes correct NodeParent contains always the whole path to the node. – Rajashekhar Sheelvant Nov 24 '18 at 01:58

1 Answers1

0

For something like this it is easiest to first create a nested object with the root node names as keys for top level which can be done with Array#reduce().

Then split the NodeName values into array and use another reduce() to walk through the parents to get specific parent to push to

Finally get the outer array from the main object using Object.values()

const map = data.reduce((a,{Node,NodeParent})=>{
   if(!NodeParent){
      a[Node] ={ Node, children:[] };
   }else{     
      const parent = NodeParent.split(/;|:/g).reduce((a,c)=>{
           a[c] = a[c] || { Node:c, children:[] };
           return a[c]
      },a);
     
      parent.children.push({Node})
   }
   return a;
},{});

const res = Object.values(map);

console.log(JSON.stringify(res,null,4));
.as-console-wrapper {  max-height: 100%!important;}
<script>
const data = [
{ "Node": "Node1", "NodeParent": "" },
{ "Node": "Node1A", "NodeParent": "Node1" },
{ "Node": "Node1B", "NodeParent": "Node1" },
{ "Node": "Node2", "NodeParent": "" },
{ "Node": "Node2A", "NodeParent": "Node2" },
{ "Node": "Node2B", "NodeParent": "Node2" },
{ "Node": "Node3", "NodeParent": "" },
{ "Node": "Node3A", "NodeParent": "Node3" },
{ "Node": "Node3A1", "NodeParent": "Node3;Node3A" },
{ "Node": "Node3A2", "NodeParent": "Node3;Node3A" },
{ "Node": "Node3A3", "NodeParent": "Node3;Node3A" },
{ "Node": "Node3A1x", "NodeParent": "Node3;Node3A:Node3A1" },
{ "Node": "Node3A1y", "NodeParent": "Node3;Node3A:Node3A1" },
{ "Node": "Node3A1z", "NodeParent": "Node3;Node3A:Node3A1" },
{ "Node": "Node3B", "NodeParent": "Node3" },
{ "Node": "Node3B1", "NodeParent": "Node3;Node3B" },
{ "Node": "Node3B2", "NodeParent": "Node3;Node3B" },
{ "Node": "Node3B3", "NodeParent": "Node3;Node3B" },
{ "Node": "Node3B1x", "NodeParent": "Node3;Node3B:Node3B1" },
{ "Node": "Node3B1y", "NodeParent": "Node3;Node3B:Node3B1" },
{ "Node": "Node3B1z", "NodeParent": "Node3;Node3B:Node3B1" }]
</script>
charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • your solution is extremely helpful, but the output is bit deviated from the desired output. Your Code snippet Output: "Node": "Node3", "children": [ { "Node": "Node3A" } ], "Node3A": { "Node": "Node3A", "children": [ {"Node": "Node3A1" }, {"Node": "Node3A2" }, { "Node": "Node3A3" }] Desired Output: "Node": "Node3", "children": [{ "Node": "Node3A", "children": [ { "Node": "Node3A1", "children": [ {"Node": "Node3A1x"}, {"Node": "Node3A1y"}, {"Node": "Node3A1z"}]}, {"Node": "Node3A2"}, {"Node": "Node3A3"}] Hope this helps – Rajashekhar Sheelvant Nov 23 '18 at 04:17
  • Yes I see it. Didn't notice that first time. Will work on it a bit and let you know – charlietfl Nov 23 '18 at 04:27