Reputation: 517
I am working on a treeview and I created a class Node, consisting of a name and a list of children.
class Node {
constructor(name, childNodes) {
this.name = name;
this.childNodes = childNodes;
}
}
I am trying to create an object looking like the object "tree" in the image below. Every Node has a attribute called "nodes" which is the childNode-Array. I got very close to creating the same tree, but in my version there is an extra "Array"-Layer around each of the Child nodes (see the recTreeview()-Element):
I am not sure how to fix this problem. The array has to be created to contain the childnodes. Here is the code where the treeview Element is created:
function recTreeview(currentNode, treeview) {
var tempChildren = [];
currentNode.children.forEach(child => {
tempChildren.push(recTreeview(child, []));
});
treeview.push({
text: currentNode.name,
nodes: tempChildren
});
return treeview;
}
Is there anything I can do? Update: A Code-Snippet:
class Node {
constructor(name, children) {
this.children = children;
this.name = name;
}
}
function recTreeview(currentNode, treeview) {
var tempChildren = [];
currentNode.children.forEach(child => {
tempChildren.push(recTreeview(child, []));
});
treeview.push({
text: currentNode.name,
nodes: tempChildren
});
return treeview;
}
child1 = new Node("child1", []);
child2 = new Node("child2", []);
parent = new Node("Parent", [child1, child2]);
var tree = [
{
text: "Parent 1",
nodes: [
{
text: "Child 1"
},
{
text: "Child 2"
}
]
}
];
<button onClick="console.log(recTreeview(parent, []));">Wrong</button>
<button onClick="console.log(tree);">Right</button>
Upvotes: 1
Views: 1314
Reputation: 31712
The extra array is comming from tempChildren.push(recTreeview(child, []));
. Because you are pushing the return value of recTreeview
(which is an array) to the children array tempChildren
.
Instead of pushing the new array to tempChildren
, you should pass tempChildren
as the parameter to recTreeview
:
currentNode.children.forEach(child => {
recTreeview(child, tempChildren);
});
So that the children will be pushed directly to the tempChildren
array instead of getting wrapped in the extra array recTreeview
is creating.
Example:
class Node {
constructor(name, children) {
this.children = children;
this.name = name;
}
}
function recTreeview(currentNode, treeview) {
var tempChildren = [];
currentNode.children.forEach(child => {
recTreeview(child, tempChildren);
});
treeview.push({
text: currentNode.name,
nodes: tempChildren
});
return treeview;
}
child1 = new Node("child1", []);
child2 = new Node("child2", []);
parent = new Node("Parent", [child1, child2]);
var tree = [
{
text: "Parent 1",
nodes: [
{
text: "Child 1"
},
{
text: "Child 2"
}
]
}
];
<button onClick="console.log(recTreeview(parent, []));">Not Wrong Anymore</button>
<button onClick="console.log(tree);">Right</button>
Note:
If you want to get rid of that empty nodes
array if there are no children, then change this:
treeview.push({
text: currentNode.name,
nodes: tempChildren
});
To:
var node = {
text: currentNode.name
};
if(tempChildren.length) {
node.nodes = tempChildren;
}
treeview.push(node);
Which only adds the nodes
property if the tempChildren
array is not empty.
Upvotes: 2