I grab a list of data from the server and I have to convert it.
Part of this is turning it into a 3 dimensional array. After the "myArr[i].children.push(temp);" it leaves copies of the objects that were pushed in the root of the array. Can I either push without copying or how would I delete these? (I have underscore js included, I know they have good array functions :))
for (var i = 0; i < myArr.length; i++) {
myArr[i].children = [];
for (var q = 0; q < myArr.length; q++) {
if (myArr[i].id == myArr[q].parentid) {
var temp = {
id: myArr[q].id,
index: myArr[q].index,
text: myArr[q].text
}
myArr[i].children.push(temp);
};
};
};
The Data
[{
"id": "5",
"parentid": "0",
"text": "Device Guides",
"index": "0"
}, {
"id": "6",
"parentid": "0",
"text": "Pre-Sales Evaluation",
"index": "1"
}, {
"id": "7",
"parentid": "0",
"text": "Router Setup Guides",
"index": "2"
}, {
"id": "9",
"parentid": "7",
"text": "Sonicwall",
"index": "0"
}, {
"id": "10",
"parentid": "5",
"text": "Grandstream GXP-21XX",
"index": "1"
}, {
"id": "11",
"parentid": "5",
"text": "Polycom Soundstation\/Soundpoint",
"index": "2"
}, {
"id": "12",
"parentid": "7",
"text": "Cisco",
"index": "1"
}, {
"id": "15",
"parentid": "0",
"text": "Post-Sales Implementation Check List",
"index": "7"
}, {
"id": "16",
"parentid": "15",
"text": "Porting and New Number Details",
"index": "0"
}, {
"id": "18",
"parentid": "15",
"text": "Partner Setup",
"index": "1"
}, {
"id": "19",
"parentid": "15",
"text": "test",
"index": "2"
}, {
"id": "20",
"parentid": "0",
"text": "test",
"index": "11"
}, {
"id": "21",
"parentid": "15",
"text": "test",
"index": "3"
}, {
"id": "23",
"parentid": "5",
"text": "New Polycom",
"index": "0"
}, {
"id": "24",
"parentid": "0",
"text": "Test Markup",
"index": "14"
}, {
"id": "25",
"parentid": "0",
"text": "test",
"index": "15"
}]
After it is formated:
{
"children": [{
"id": "5",
"parentid": "0",
"text": "Device Guides",
"index": "1",
"children": [{
"id": "10",
"index": "0",
"text": "Grandstream GXP-21XX"
}, {
"id": "11",
"index": "1",
"text": "Polycom Soundstation/Soundpoint"
}, {
"id": "23",
"index": "2",
"text": "New Polycom"
}]
}, {
"id": "6",
"parentid": "0",
"text": "Pre-Sales Evaluation",
"index": "0",
"children": []
}, {
"id": "7",
"parentid": "0",
"text": "Router Setup Guides",
"index": "2",
"children": [{
"id": "9",
"index": "0",
"text": "Sonicwall"
}, {
"id": "12",
"index": "1",
"text": "Cisco"
}]
}, {
"id": "9",
"parentid": "7",
"text": "Sonicwall",
"index": "0",
"children": []
}, {
"id": "10",
"parentid": "5",
"text": "Grandstream GXP-21XX",
"index": "0",
"children": []
}, {
"id": "11",
"parentid": "5",
"text": "Polycom Soundstation/Soundpoint",
"index": "1",
"children": []
}, {
"id": "12",
"parentid": "7",
"text": "Cisco",
"index": "1",
"children": []
}, {
"id": "15",
"parentid": "0",
"text": "Post-Sales Implementation Check List",
"index": "7",
"children": [{
"id": "16",
"index": "0",
"text": "Porting and New Number Details"
}, {
"id": "18",
"index": "1",
"text": "Partner Setup"
}, {
"id": "19",
"index": "2",
"text": "test"
}, {
"id": "21",
"index": "3",
"text": "test"
}]
}, {
"id": "16",
"parentid": "15",
"text": "Porting and New Number Details",
"index": "0",
"children": []
}, {
"id": "18",
"parentid": "15",
"text": "Partner Setup",
"index": "1",
"children": []
}, {
"id": "19",
"parentid": "15",
"text": "test",
"index": "2",
"children": []
}, {
"id": "20",
"parentid": "0",
"text": "test",
"index": "11",
"children": []
}, {
"id": "21",
"parentid": "15",
"text": "test",
"index": "3",
"children": []
}, {
"id": "23",
"parentid": "5",
"text": "New Polycom",
"index": "2",
"children": []
}, {
"id": "24",
"parentid": "0",
"text": "Test Markup",
"index": "14",
"children": []
}, {
"id": "25",
"parentid": "0",
"text": "test",
"index": "15",
"children": []
}]
}
Here you go
tree = {0: {children: []}}
data.forEach(function(x) {
x.children = tree[x.id] ? tree[x.id].children : [];
tree[x.id] = x;
if(!tree[x.parentid])
tree[x.parentid] = {children: []}
tree[x.parentid].children.push(x)
})
result = tree[0].children
This solution is linear (iterates over the array just once) and doesn't require any pre-sorting.
http://jsfiddle.net/U47WY/
and here's how to convert the tree back to the linear array:
function flatten(source) {
return source.reduce(function(a, x) {
var children = x.children;
delete x.children;
return a.concat([x], flatten(x.children))
}, []);
}
Following on from a friendly discussion in the comments :
var zeroObj = {"children":[]};
for (var i = 0; i < myArr.length; i++) {
if(myArr[i].parentid === 0) {
zeroObj.children.push(myArr[i]);
} else {
for (var q = 0; q < myArr.length; q++) {
if (myArr[i].parentid == myArr[q].id) {
myArr[q].children = myArr[q].children || [];
myArr[q].children.push(myArr[i]);
};
};
}
};
Related
I have a hierarchy tree JSON with multiple level of nesting. When i am trying to loop through the JSON for displaying tree structure in UI. I am ending up with cyclic redundancy since parent ID is same at different level. I need to add unique identifiers for parentID and ID, so in recursive call it does not end up in infinite loop.
Sample JSON :
[
{
"id": "12",
"text": "Man"
},
{
"id": "6",
"parentId": "12",
"text": "Boy"
},
{
"id": "9",
"parentId": "6",
"text": "Boy-Boy"
},
{
"id": "13",
"parentId": "9",
"text": "Boy-Boy-Boy"
},
{
"id": "7",
"parentId": "12",
"text": "Other"
},
{
"id": "6",
"parentId": "7",
"text": "Boy"
},
{
"id": "9",
"parentId": "6",
"text": "Boy-Boy"
},
{
"id": "13",
"parentId": "9",
"text": "Boy-Boy-Boy"
}
I have tried by adding depth to each level but not able to maintain the ParentId and Id relationship.
var depthArray = []
function addDepth(arr, depth = 0) {
arr.forEach(obj => {
obj.id = obj.id + '-' + depth;
if(obj.children !== undefined) {
addDepth(obj.children, depth + 1)
}})
return arr;
}
[
{
"id": "12",
"text": "Man"
},
{
"id": "6",
"parentId": "12",
"text": "Boy"
},
{
"id": "9",
"parentId": "6",
"text": "Boy-Boy"
},
{
"id": "13",
"parentId": "9",
"text": "Boy-Boy-Boy"
},
{
"id": "7",
"parentId": "12",
"text": "Other"
},
{
"id": "6-1",
"parentId": "7",
"text": "Boy"
},
{
"id": "9-1",
"parentId": "6-1",
"text": "Boy-Boy"
},
{
"id": "13-1",
"parentId": "9-1",
"text": "Boy-Boy-Boy"
}
]
Your recursion does not work, what about this ?
But not sure how to rename IDs:
'use strict';
function addDepth(arr, id, depth) {
if(depth === undefined) depth = 0;
if(id !== undefined)
arr.forEach(obj => {
if(id == obj.parentId) {
if(depth) obj.parentId += '-' + depth;
addDepth(arr, obj.id, depth + 1)
}
})
else arr.forEach(obj => { addDepth(arr, obj.id, depth); });
return arr;
}
console.log(addDepth(
[
{
"id": "12",
"text": "Man"
},
{
"id": "6",
"parentId": "12",
"text": "Boy"
},
{
"id": "9",
"parentId": "6",
"text": "Boy-Boy"
},
{
"id": "13",
"parentId": "9",
"text": "Boy-Boy-Boy"
},
{
"id": "7",
"parentId": "12",
"text": "Other"
},
{
"id": "6",
"parentId": "7",
"text": "Boy"
},
{
"id": "9",
"parentId": "6",
"text": "Boy-Boy"
},
{
"id": "13",
"parentId": "9",
"text": "Boy-Boy-Boy"
}
]
));
Hard to guess how structure may look like, but made a supposed output by hand and then similar code - looking up only (not sure how to distinguish same records with parentId difference):
12 Man
12 6 Man Boy
12 6 9 Man Boy Boy-Boy
12 6 9 13 Man Boy Boy-Boy Boy-Boy-Boy
12 7 Man Other
12 7 Man Other Boy
12 7 6 9 Man Other Boy Boy-Boy
12 7 6 9 13 Man Other Boy Boy-Boy Boy-Boy-Boy
var data = GetData();
var arr = [data[0].text], parent;
for(var i=0;i<data.length;i++) {
if(parent = data[i].parentId) {
arr.push(data[i].text); // we have parentId, so iterate back
for(var j=i;j >= 0;j--) {
if(data[j].id == parent) {
arr.push(data[j].text); // & colect text properties
if(data[j].parentId) {
parent = data[j].parentId;
j = i;
}
}
}
}
console.log(arr.reverse().join(" -> "));
arr = [];
}
function GetData() { return [
{
"id": "12",
"text": "Man"
},
{
"id": "6",
"parentId": "12",
"text": "Boy"
},
{
"id": "9",
"parentId": "6",
"text": "Boy-Boy"
},
{
"id": "13",
"parentId": "9",
"text": "Boy-Boy-Boy"
},
{
"id": "7",
"parentId": "12",
"text": "Other"
},
{
"id": "6",
"parentId": "7",
"text": "Boy"
},
{
"id": "9",
"parentId": "6",
"text": "Boy-Boy"
},
{
"id": "13",
"parentId": "9",
"text": "Boy-Boy-Boy"
}
];
}
Below is the sample data(Hierarchical data) I want to only that array of object which has IsChecked = true and also all its children with condition isChecked =true.
$scope.treedData = [{
"id": "1",
"text": "Women",
"parentId": null,
"IsChecked": true,
"children": [{
"id": "4",
"text": "Jeans",
"parentId": "1",
"IsChecked": true,
"children": [
{ "id": "5", "text": "Jeans child", "parentId": "4", "IsChecked": true, "children": [] },
{ "id": "6", "text": "Jeans child child", "parentId": "4", "IsChecked": false, "children": [] }
]
}]
},
{
"id": "2",
"text": "Men",
"parentId": null,
"IsChecked": false,
"children": [{ "id": "10", "text": "Sweatshirts", "parentId": "2", "IsChecked": false, "children": [] }]
},
{
"id": "3",
"text": "Kids",
"parentId": null,
"IsChecked": true,
"children": [{ "id": "12", "text": "Toys", "parentId": "3", "IsChecked": false, "children": [] }]
}
];
You can use reduce for that, and use recursion to apply the filter to the children hierarchy as well:
var treeData = [
{ "id": "1", "text": "Women", "parentId": null, "IsChecked": true,
"children": [
{ "id": "4", "text": "Jeans", "parentId": "1", "IsChecked": false, "children":[
{ "id": "5", "text": "Jeans child", "parentId": "4", "IsChecked": true, "children":[] },
{ "id": "6", "text": "Jeans child child", "parentId": "4", "IsChecked": false, "children":[] }
] }]
},
{ "id": "2", "text": "Men", "parentId": null, "IsChecked": false,
"children": [{ "id": "10", "text": "Sweatshirts", "parentId": "2", "IsChecked": false, "children":[]}]
},
{"id": "3", "text": "Kids", "parentId": null, "IsChecked": true,
"children": [{ "id": "12", "text": "Toys", "parentId": "3", "IsChecked": false, "children":[] }]
}
];
checkedTreeData = treeData.reduce(function checkedOnly (acc, obj) {
return obj.IsChecked
? acc.concat(Object.assign({}, obj, { children: obj.children.reduce(checkedOnly, []) }))
: acc;
}, []);
console.log(checkedTreeData);
.as-console-wrapper { max-height: 100% !important; top: 0; }
NB: In JavaScript there is an unwritten rule to not use an initial capital letter for property names, so IsChecked would be with a lower case i: isChecked. Initial capital letters are commonly used for constructors (classes).
Alternative with .filter()
function filterChecked(treeData) {
return treeData.filter(obj => obj.IsChecked)
.map(obj => Object.assign({}, obj, obj.children ?
{ children: filterChecked(obj.children) } : {}))
}
var treeData = [
{ "id": "1", "text": "Women", "parentId": null, "IsChecked": true,
"children": [
{ "id": "4", "text": "Jeans", "parentId": "1", "IsChecked": false, "children":[
{ "id": "5", "text": "Jeans child", "parentId": "4", "IsChecked": true, "children":[] },
{ "id": "6", "text": "Jeans child child", "parentId": "4", "IsChecked": false, "children":[] }
] }]
},
{ "id": "2", "text": "Men", "parentId": null, "IsChecked": false,
"children": [{ "id": "10", "text": "Sweatshirts", "parentId": "2", "IsChecked": false, "children":[]}]
},
{"id": "3", "text": "Kids", "parentId": null, "IsChecked": true,
"children": [{ "id": "12", "text": "Toys", "parentId": "3", "IsChecked": false, "children":[] }]
}
];
console.log(filterChecked(treeData));
.as-console-wrapper { max-height: 100% !important; top: 0; }
use Lodash _.filter and _.every
_.filter(treedData, function(item) {
return _.every([
item.IsChecked,
_.every(item.children, 'IsChecked')
]);
});
if you also want to check condition of children of children you can do it recursively like
_.filter(treedData, function check(item) {
return _.every([
item.IsChecked,
_.size(item.children) === 0 || _.every(item.children, check)
]);
});
I'm having a major brain fart. I have a java application that adds items to carts, and I'm using JSOUP to parse the html document since it can't run any javascript scripts. So I extracted this out of the getElementsByTag().html(); function. And now I need to find the value 1038, but while keeping in mind the values is not always 1038. So I would need it to search attribute -> 92 -> options -> id = 1038.
var spConfig = new Product.Config({
"attributes": {
"92": {
"id": "92",
"code": "color",
"label": "Color",
"options": [{
"id": "1038",
"label": "GREEN",
"price": "0",
"oldPrice": "0",
"products": ["94035", "94036", "94037", "94038", "94039", "94040", "94041", "94042", "94043", "94044"]
}]
},
"196": {
"id": "196",
"code": "size",
"label": "Size",
"options": [{
"id": "189",
"label": "8 ",
"price": "0",
"oldPrice": "0",
"products": ["94041"]
}, {
"id": "188",
"label": "8.5",
"price": "0",
"oldPrice": "0",
"products": ["94042"]
}, {
"id": "187",
"label": "9",
"price": "0",
"oldPrice": "0",
"products": ["94043"]
}, {
"id": "186",
"label": "9.5",
"price": "0",
"oldPrice": "0",
"products": ["94044"]
}, {
"id": "185",
"label": "10",
"price": "0",
"oldPrice": "0",
"products": ["94035"]
}, {
"id": "184",
"label": "10.5",
"price": "0",
"oldPrice": "0",
"products": ["94036"]
}, {
"id": "183",
"label": "11",
"price": "0",
"oldPrice": "0",
"products": ["94037"]
}, {
"id": "182",
"label": "11.5",
"price": "0",
"oldPrice": "0",
"products": ["94038"]
}, {
"id": "181",
"label": "12",
"price": "0",
"oldPrice": "0",
"products": ["94039"]
}, {
"id": "179",
"label": "13",
"price": "0",
"oldPrice": "0",
"products": ["94040"]
}]
}
},
"template": "$#{price}",
"basePrice": "129.98",
"oldPrice": "180",
"productId": "94013",
"chooseText": "Choose an Option...",
"taxConfig": {
"includeTax": false,
"showIncludeTax": false,
"showBothPrices": false,
"defaultTax": 0,
"currentTax": 0,
"inclTaxTitle": "Incl. Tax"
}
});
I need to receive the value "1038", but it can't just be a search function for integer 1038, because that value can possibly change in my script.
I am using angular JS and one of their examples:http://jsfiddle.net/furf/EJGHX/
I need to take the data when the update function occurs and add some values to it before I send to the server. (If doing this with angular instead of js would be better let me know)
I'm trying to get the 'parentid' and the 'index' and update the children.
Here is the data I'm looping through
{
"children": [{
"id": "5",
"parentid": "0",
"text": "Device Guides",
"index": "1",
"children": [{
"id": "10",
"index": "0",
"text": "Grandstream GXP-21XX"
}, {
"id": "11",
"index": "1",
"text": "Polycom Soundstation/Soundpoint"
}, {
"id": "23",
"index": "2",
"text": "New Polycom"
}]
}, {
"id": "6",
"parentid": "0",
"text": "Pre-Sales Evaluation",
"index": "0",
"children": []
}, {
"id": "7",
"parentid": "0",
"text": "Router Setup Guides",
"index": "2",
"children": [{
"id": "9",
"index": "0",
"text": "Sonicwall"
}, {
"id": "12",
"index": "1",
"text": "Cisco"
}]
}, {
"id": "9",
"parentid": "7",
"text": "Sonicwall",
"index": "0",
"children": []
}, {
"id": "10",
"parentid": "5",
"text": "Grandstream GXP-21XX",
"index": "0",
"children": []
}, {
"id": "11",
"parentid": "5",
"text": "Polycom Soundstation/Soundpoint",
"index": "1",
"children": []
}, {
"id": "12",
"parentid": "7",
"text": "Cisco",
"index": "1",
"children": []
}, {
"id": "15",
"parentid": "0",
"text": "Post-Sales Implementation Check List",
"index": "7",
"children": [{
"id": "16",
"index": "0",
"text": "Porting and New Number Details"
}, {
"id": "18",
"index": "1",
"text": "Partner Setup"
}, {
"id": "19",
"index": "2",
"text": "test"
}, {
"id": "21",
"index": "3",
"text": "test"
}]
}, {
"id": "16",
"parentid": "15",
"text": "Porting and New Number Details",
"index": "0",
"children": []
}, {
"id": "18",
"parentid": "15",
"text": "Partner Setup",
"index": "1",
"children": []
}, {
"id": "19",
"parentid": "15",
"text": "test",
"index": "2",
"children": []
}, {
"id": "20",
"parentid": "0",
"text": "test",
"index": "11",
"children": []
}, {
"id": "21",
"parentid": "15",
"text": "test",
"index": "3",
"children": []
}, {
"id": "23",
"parentid": "5",
"text": "New Polycom",
"index": "2",
"children": []
}, {
"id": "24",
"parentid": "0",
"text": "Test Markup",
"index": "14",
"children": []
}, {
"id": "25",
"parentid": "0",
"text": "test",
"index": "15",
"children": []
}]
}
This is how I'm currently looping through it, but it only gets the first dimension
for (i = 0, l = data.length; i < l; i++) {
parentid = data[i].id == null ? '0' : data[i].id;
data[i].index = i;
if (data[i].children) {
if (data[i].children.length > 0) {
for (q = 0, r = data[i].children.length; q < r; q++) {
data[i].children[q].parentid = parentid;
data[i].children[q].index = q;
}
}
}
}
I found this one on another fiddle, but I don't know how I would grab the parentid or the index
$.each(target.children, function(key, val) { recursiveFunction(key, val) });
function recursiveFunction(key, val) {
actualFunction(key, val);
var value = val['children'];
if (value instanceof Object) {
$.each(value, function(key, val) {
recursiveFunction(key, val)
});
}
}
function actualFunction(key, val) {}
If I'm understanding you correctly, you want each 'child' to have a parentID (defined by its parent; 0 otherwise) and an index (based on its position within it sibling set).
function normalize(parent) {
if (parent && parent.children) {
for (var i = 0, l = parent.children.length; i < l; ++i) {
var child = parent.children[i];
child.index = i;
if (!child.parentId) child.parentId = parent.id || '0';
normalize(child);
}
}
}
normalize(data);
Recursion is calling function inside the same function. Your sample is not a recursion at all;
function runRecursive(input) {
for (var i = 0, l = input.length; i < l; i++) {
var current = input[i];
parentid = current.id == null ? '0' : current.id;
current.index = i;
if (current.children && current.children.length > 0) {
runRecursive(current.children);
};
};
};
runRecursive(data.children);
Also you should define i and l with var keyword, otherwise it will be located in window context and recursion logic will broken.
Though I don't get what is parentid variable for and why it defined outside visible code.
I have to convert JSON to the format below, I'm having a problem converting it back.
Here is the current format
[{
"id": "5",
"parentid": "0",
"text": "Device Guides",
"index": 0,
"children": [{
"id": "10",
"text": "Grandstream GXP-21XX",
"index": 0
}, {
"id": "11",
"text": "Polycom Soundstation/Soundpoint",
"index": 1
}, {
"id": "23",
"text": "New Polycom",
"index": 2
}]
}, {
"id": "6",
"parentid": "0",
"text": "Pre-Sales Evaluation",
"index": 1,
"children": []
}, {
"id": "7",
"parentid": "0",
"text": "Router Setup Guides",
"index": 2,
"children": [{
"id": "9",
"text": "Sonicwall",
"index": 0
}, {
"id": "12",
"text": "Cisco",
"index": 1
}]
}, {
"id": "9",
"parentid": "7",
"text": "Sonicwall",
"index": 3,
"children": []
}, {
"id": "10",
"parentid": "5",
"text": "Grandstream GXP-21XX",
"index": 4,
"children": []
}, {
"id": "11",
"parentid": "5",
"text": "Polycom Soundstation/Soundpoint",
"index": 5,
"children": []
}, {
"id": "12",
"parentid": "7",
"text": "Cisco",
"index": 6,
"children": []
}]
Here is the format I need it in:
[{
"id": "5",
"parentid": "0",
"text": "Device Guides",
"index": "0"
}, {
"id": "6",
"parentid": "0",
"text": "Pre-Sales Evaluation",
"index": "0"
}, {
"id": "7",
"parentid": "0",
"text": "Router Setup Guides",
"index": "0"
}, {
"id": "9",
"parentid": "7",
"text": "Sonicwall",
"index": "0"
}, {
"id": "10",
"parentid": "5",
"text": "Grandstream GXP-21XX",
"index": "0"
}, {
"id": "11",
"parentid": "5",
"text": "Polycom Soundstation\/Soundpoint",
"index": "0"
}, {
"id": "12",
"parentid": "7",
"text": "Cisco",
"index": "0"
}]
Basically, I have to nest it for the script I'm using but the server is expecting to see it flattened, in the current format the 3rd object dimension starts with "children". I need to unnest children and keep the objects going like the format I need it in.
A first solution, granted you don't want the resulting array to be sorted based on the id:
function visitor(graph) {
var i, l,
nodes=[],
visited=[];
function clone(n) {
// improve the function yourself I'm lazy
var i,l,
props=["id","parentid","index","text"],
result={};
for (i = 0, l = props.length; i < l; i++) {
if (n[props[i]]) {
result[props[i]]= n[props[i]];
}
}
return result;
}
function helper (node) {
var i, limit;
if (visited.indexOf(node.id) == -1) {
visited.push(node.id);
nodes.push(clone(node));
if( node.children) {
for (i = 0, limit = node.children.length; i < limit; i++) {
helper(node.children[i]);
}
}
}
}
for (i = 0, l = graph.length; i < l; i++) {
helper(graph[i]);
}
return nodes;
}
var graph = [{
"id": "5",
"parentid": "0",
"text": "Device Guides",
"index": 0,
"children": [{
"id": "10",
"text": "Grandstream GXP-21XX",
"index": 0
}, {
"id": "11",
"text": "Polycom Soundstation/Soundpoint",
"index": 1
}, {
"id": "23",
"text": "New Polycom",
"index": 2
}]
}, {
"id": "6",
"parentid": "0",
"text": "Pre-Sales Evaluation",
"index": 1,
"children": []
}, {
"id": "7",
"parentid": "0",
"text": "Router Setup Guides",
"index": 2,
"children": [{
"id": "9",
"text": "Sonicwall",
"index": 0
}, {
"id": "12",
"text": "Cisco",
"index": 1
}]
}, {
"id": "9",
"parentid": "7",
"text": "Sonicwall",
"index": 3,
"children": []
}, {
"id": "10",
"parentid": "5",
"text": "Grandstream GXP-21XX",
"index": 4,
"children": []
}, {
"id": "11",
"parentid": "5",
"text": "Polycom Soundstation/Soundpoint",
"index": 5,
"children": []
}, {
"id": "12",
"parentid": "7",
"text": "Cisco",
"index": 6,
"children": []
}];
nodes = visitor(graph);
And yes, I know, the helper function relay on side effects but I've scoped them into the visitor function to reduce harm and there is room for improvements (at least sorting the resulting array based on the id) but I will leave them to you