Convert Leaf Nodes Into Child under Child for Json Object In D3js tree
Convert Leaf Nodes Into Child under Child for Json Object In D3js tree
The Overall Context is to find the leaf node of every parent(x) and children(x1) if there are more than 2 leaf nodes make them the child's as one under another
I Tried to use loadash in Nodejs but I was unable to get the expected result
I have a JSON Data
"Id": "1",
"name": "x",
"parent": "",
"children": [
"Id": "2",
"name": "x1",
"parent": "1",
"children": [
"Id": "3",
"name": "x2",
"parent": "2"
,
"Id": "4",
"name": "x3",
"parent": "2"
,
"Id": "5",
"name": "x4",
"parent": "2"
,
"Id": "6",
"name": "x5",
"parent": "2"
,
"Id": "7",
"name": "x6",
"parent": "2"
,
"Id": "8",
"name": "x7",
"parent": "2"
]
,
"Id": "9",
"name": "x8",
"parent": "1"
,
"Id": "10",
"name": "x10",
"parent": "1"
,
"Id": "11",
"name": "x9",
"parent": "1"
,
"Id": "12",
"name": "x11",
"parent": "1"
]
I would like to change into the below format
"Id": "1",
"name": "x",
"parent": "",
"children": [
"Id": "2",
"name": "x1",
"parent": "1",
"children": [
"Id": "3",
"name": "x2",
"IC": "Yes",
"parent": "2",
"children": [
"Id": "5",
"name": "x4",
"IC": "Yes",
"parent": "2",
"children": [
"Id": "7",
"parent": "2",
"name": "x6"
]
]
,
"Id": "4",
"name": "x3",
"IC": "Yes",
"parent": "2",
"children": [
"Id": "5",
"name": "x5",
"IC": "Yes",
"parent": "2",
"children": [
"Id": "7",
"name": "x7",
"IC": "Yes",
"parent": "2"
]
]
]
,
"Id": "9",
"name": "x8",
"parent": "1",
"children": [
"Id": "10",
"name": "x10",
"IC": "Yes",
"parent": "1"
]
,
"Id": "11",
"name": "x9",
"parent": "1",
"children": [
"Id": "11",
"name": "x11",
"parent": "1",
"IC": "Yes"
]
]
Note:
1. If there are 8 leaf nodes it should be split 4+4,
2. If there are 9 leaf nodes it should be split 5+4,
3. In the same way, If it has 13 it can be split into 7+6.
any help would be appreciated
thanks in advance
Thanks ggorlen for mentioning that I have put the valid JSON now
– Sri
Sep 9 '18 at 22:12
Thanks. I'm not 100% clear on your requested transformation, though. Do you only want to consider leaf nodes in the root object at depth 0? Because
x1 has more than 2 leaf nodes but wasn't altered. How do you handle a case with an odd number of leaf nodes? Please confirm.– ggorlen
Sep 9 '18 at 22:27
x1
Yes it is for the root and the children (x1)
– Sri
Sep 9 '18 at 22:37
If it's for the children of
x1, would you mind reflecting your output example to show that? I don't want to code something up for you that isn't what you're asking for.– ggorlen
Sep 9 '18 at 22:47
x1
1 Answer
1
The following code will take all leaf nodes and create 2 even branches from them. The output is not identical to yours, but you mention in your comments that the branches can be built randomly from the leaf nodes, and this code respects that requirement.
const input =
"name": "x",
"children": [
"name": "x1",
"children": [
"name": "x2"
,
"name": "x3"
,
"name": "x4"
,
"name": "x5"
,
"name": "x6"
,
"name": "x7"
]
,
"name": "x8"
,
"name": "x10"
,
"name": "x9"
,
"name": "x11"
]
;
function cutLeafNodes(node)
if(!node.children)
return;
const leaves = ;
const branches = ;
node.children.forEach(child =>
if(child.children)
branches.push(child);
else
leaves.push(child);
);
node.children = branches;
return leaves;
function reorderLeaves(nodes)
if(!nodes)
return;
const midpoint = nodes.length / 2;
const newChildren = ;
newChildren.push(createAncestry(nodes.splice(0, midpoint)));
newChildren.push(createAncestry(nodes));
return newChildren;
function createAncestry(nodes)
let currentChild = nodes[0];
const firstChild = currentChild;
for (let i = 1; i < nodes.length; i++)
currentChild.children = [nodes[i]];
currentChild = currentChild.children[0];
return firstChild;
function reorganizeTree(node)
const leaves = cutLeafNodes(node);
if(node.children)
node.children.forEach(child =>
reorganizeTree(child);
);
if(leaves)
const newBranches = reorderLeaves(leaves);
newBranches.forEach(branch =>
node.children.push(branch);
)
return node;
const output = reorganizeTree(input);
console.debug(output);
Thanks a lot, Guillaume CR I spent some many nights for this I really appreciate your help.
– Sri
Sep 11 '18 at 18:35
@Sri You're welcome. It was an interesting problem to solve.
– Guillaume CR
Sep 11 '18 at 18:43
@ Guillaume CR I need help with small thing How do I add "IC": "Yes", for all leaf nodes in the JSON.Thanks for the help in advance.I tried to add but it is adding as a new object instead of adding to leaf node
– Sri
Sep 12 '18 at 20:02
@Sri node.IC = 'Yes';
– Guillaume CR
Sep 13 '18 at 13:54
Hi Guillaume. I am trying to make half nodes when the count of leaf nodes is more than "6"
function reorderLeaves(nodes) if(!nodes) return; const newChildren = ; if(nodes.length>5) const midpoint = nodes.length; newChildren.push(createAncestry(nodes.splice(0, midpoint/2))); newChildren.push(createAncestry(nodes)); return newChildren; when i trying this i am unable to see the expected out put. If you could let me know where i am doing wrong that would be great thanks – Sri
Jan 7 at 18:35
function reorderLeaves(nodes) if(!nodes) return; const newChildren = ; if(nodes.length>5) const midpoint = nodes.length; newChildren.push(createAncestry(nodes.splice(0, midpoint/2))); newChildren.push(createAncestry(nodes)); return newChildren; when i trying this i am unable to see the expected out put. If you could let me know where i am doing wrong that would be great thanks
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
This doesn't appear to be valid JSON. Please run it through jsonlint.com and repost.
– ggorlen
Sep 9 '18 at 21:56