Reputation: 325
I have a JSON that is :
var json = [{
"name": "0xcd963fe5b4d9de5380130d6c6b6cfb5d3b903b1f",
"parent": "null"
}, {
"name": "0xe8f84d8ad5850d66bd289ce3199753c35f4cbf40",
"parent": "0xcd963fe5b4d9de5380130d6c6b6cfb5d3b903b1f"
}, {
"name": "0x8fa01b60f503a3873c1b02ef351112f57cdd818e",
"parent": "0xe8f84d8ad5850d66bd289ce3199753c35f4cbf40"
}, {
"name": "0x753a018eca49f1b1e8b46b88d6a7b449478740e0",
"parent": "0xcd963fe5b4d9de5380130d6c6b6cfb5d3b903b1f"
}]
I'm trying to using Javascript to rewrite this into a new JSON that would be ordered like:
var json = [{
"name": "0xcd963fe5b4d9de5380130d6c6b6cfb5d3b903b1f",
"parent": "null",
"children": [{
"name": "0x753a018eca49f1b1e8b46b88d6a7b449478740e0",
"parent": "0xcd963fe5b4d9de5380130d6c6b6cfb5d3b903b1f"
}, {
"name": "0xe8f84d8ad5850d66bd289ce3199753c35f4cbf40",
"parent": "0xcd963fe5b4d9de5380130d6c6b6cfb5d3b903b1f",
"children": [{
"name": "0x8fa01b60f503a3873c1b02ef351112f57cdd818e",
"parent": "0xe8f84d8ad5850d66bd289ce3199753c35f4cbf40"
}]
}]
}]
Children would be created and nested to their parent object. Each name is unique, first object have no parent ("null"), and it's possible an object don't have children ("null" or empty array []).
I'm not used to javascript and I'm not sure how exactly I can achieve that, I tried various loop but not working, as :
json.forEach(function(link) {
var parent = link.parent = nodeByName(json,link.parent),
child = link.children = nodeByName(json,link.children);
if (parent.children) parent.children.push(child);
else parent.children = [child];
});
But this result as :
[{
"name": "0xcd963fe5b4d9de5380130d6c6b6cfb5d3b903b1f",
"parent": {
"name": "null",
"children": [{}]
},
"children": {}
}, {
"name": "0xe8f84d8ad5850d66bd289ce3199753c35f4cbf40",
"parent": {
"name": "0xcd963fe5b4d9de5380130d6c6b6cfb5d3b903b1f",
"children": [{}, {}]
},
"children": {}
}, {
"name": "0x8fa01b60f503a3873c1b02ef351112f57cdd818e",
"parent": {
"name": "0xe8f84d8ad5850d66bd289ce3199753c35f4cbf40",
"children": [{}]
},
"children": {}
}, {
"name": "0x753a018eca49f1b1e8b46b88d6a7b449478740e0",
"parent": {
"name": "0xcd963fe5b4d9de5380130d6c6b6cfb5d3b903b1f",
"children": [{}, {}]
},
"children": {}
}]
Upvotes: 0
Views: 71
Reputation: 325
As @blex mentioned in a comment, this function did exactly what I needed to achieve. Thanks a lot!
This is an adaptation of this answer: Build tree array from flat array in javascript
function list_to_tree(list) {
var map = {}, node, roots = [], i;
for (i = 0; i < list.length; i += 1) {
map[list[i].name] = i;
}
for (i = 0; i < list.length; i += 1) {
node = list[i];
if (node.parent !== "null") {
var parent = list[map[node.parent]];
if (!parent.children) {
parent.children = [];
}
parent.children.push(node);
} else {
roots.push(node);
}
}
return roots;
}
var res = list_to_tree(json)
Upvotes: 0
Reputation: 2719
You can use reduce()
, combined with a recursive function (to support many nested children levels):
function getChildren (name, items) {
return items
.filter(({ parent }) => parent === name)
.map(item => ({...item, children: getChildren(item.name, json)}));
}
const resultAsObject = json.reduce((accum, {name, parent}) => {
if (parent === "null") {
accum[name] = { name, parent, children: getChildren(name, json) };
}
return accum;
}, {});
const resultAsArray = Object.values(resultAsObject);
Upvotes: 2