dingir
asked on
Modify method to recursive
I would like some help with modifying this to a recursive function.
string nodeHtml = "<div class='fll'> <div class='tw1'>{0}</div><div class='tw2'>{1}</div> </div>";
TreeNode l1Node = null;
TreeNode l2Node = null;
TreeNode l3Node = null;
foreach (SomeList sub1 in levels.Where(d => d.Level == 1))
{
l1Node = new TreeNode(string.Format(nod eHtml, sub1.Username, sub1.UserId.ToString(), "", sub1.UserId));
foreach (SomeList sub2 in levels.Where(d => d.subUserId == sub1.UserId))
{
l2Node = new TreeNode(string.Format(nod eHtml, sub2.Username, sub2.UserId.ToString(), "", sub2.UserId));
foreach (SomeList sub3 in levels.Where(d => d.subUserId == sub2.UserId))
{
l3Node = new TreeNode(string.Format(nod eHtml, sub3.Username, sub3.UserId.ToString(), "", sub3.UserId));
foreach (SomeList sub4 in levels.Where(d => d.subUserId == sub3.UserId))
{
TreeNode n4 = new TreeNode(string.Format(nod eHtml, sub4.Username, sub4.UserId.ToString(), "", sub4.UserId));
l3Node.ChildNodes.Add(n4);
}
tw.Nodes.Add(l3Node);
l2Node.ChildNodes.Add(l3No de);
}
tw.Nodes.Add(l2Node);
l1Node.ChildNodes.Add(l2No de);
}
tw.Nodes.Add(l1Node);
tw.CollapseAll();
}
Also other ideas of optimations are welcome,
string nodeHtml = "<div class='fll'> <div class='tw1'>{0}</div><div class='tw2'>{1}</div> </div>";
TreeNode l1Node = null;
TreeNode l2Node = null;
TreeNode l3Node = null;
foreach (SomeList sub1 in levels.Where(d => d.Level == 1))
{
l1Node = new TreeNode(string.Format(nod
foreach (SomeList sub2 in levels.Where(d => d.subUserId == sub1.UserId))
{
l2Node = new TreeNode(string.Format(nod
foreach (SomeList sub3 in levels.Where(d => d.subUserId == sub2.UserId))
{
l3Node = new TreeNode(string.Format(nod
foreach (SomeList sub4 in levels.Where(d => d.subUserId == sub3.UserId))
{
TreeNode n4 = new TreeNode(string.Format(nod
l3Node.ChildNodes.Add(n4);
}
tw.Nodes.Add(l3Node);
l2Node.ChildNodes.Add(l3No
}
tw.Nodes.Add(l2Node);
l1Node.ChildNodes.Add(l2No
}
tw.Nodes.Add(l1Node);
tw.CollapseAll();
}
Also other ideas of optimations are welcome,
I forgot the last recursive call. Here is the sample again.
DaTribe
DaTribe
void Recursive(IEnumerable<SomeList> levels, string nodeHtml, TreeView tw, int depth, SomeList item, TreeNode parentNode)
{
switch(depth)
{
case 0:
levels
.Where(d => d.Level == 1)
.ToList()
.ForEach(sub =>
{
var node = new TreeNode(string.Format(nodeHtml, sub.Username, sub.UserId.ToString(), String.Empty, sub.UserId));
Recursive(levels, nodeHtml, tw, ++depth, sub, node);
tw.Nodes.Add(node);
tw.CollapseAll();
});
break;
case 1:
case 2:
case 3:
levels
.Where(d => d.subUserId == item.UserId)
.ToList()
.ForEach(sub =>
{
var node = new TreeNode(string.Format(nodeHtml, item.Username, item.UserId.ToString(), String.Empty, sub.UserId));
if (depth < 3)
{
Recursive(levels, nodeHtml, tw, ++depth, sub, node);
tw.Nodes.Add(node);
}
parentNode.ChildNodes.Add(node);
});
break;
}
}
ASKER
First: Thank's,
The thing is. There are a problem from start in this code.
There are really no variation in the clauses.
The child nodes are from the same data source, i did never got it correct in one dataset.
id subid
-- getAllWhere(subid == id)
-- -- getAllWhere(subid == id)
-- -- -- getAllWhere(subid == id)
-- -- -- -- getAllWhere(subid == id)
... and so on.. infinite.
..would be the optimal.
The thing is. There are a problem from start in this code.
There are really no variation in the clauses.
The child nodes are from the same data source, i did never got it correct in one dataset.
id subid
-- getAllWhere(subid == id)
-- -- getAllWhere(subid == id)
-- -- -- getAllWhere(subid == id)
-- -- -- -- getAllWhere(subid == id)
... and so on.. infinite.
..would be the optimal.
I will have another go however your first where clause is different.
levels.Where(d => d.Level == 1)
levels.Where(d => d.subUserId == sub1.UserId)
levels.Where(d => d.subUserId == sub2.UserId)
levels.Where(d => d.subUserId == sub3.UserId)
plus on your most inner iteration you have chosen not to add the nodes to the root of the treeview therefore forcing the logic to determine when it is at the bottom (logic varies)
DaTribe
levels.Where(d => d.Level == 1)
levels.Where(d => d.subUserId == sub1.UserId)
levels.Where(d => d.subUserId == sub2.UserId)
levels.Where(d => d.subUserId == sub3.UserId)
plus on your most inner iteration you have chosen not to add the nodes to the root of the treeview therefore forcing the logic to determine when it is at the bottom (logic varies)
DaTribe
ASKER
Thanks
The Level isn't a part of the data.
"Level" is generated and attached to the dataset on collection of data, to sort out the different levels of deep.
id subid
-- id, subid
-- -- id, subid
-- -- -- id, subid
-- -- -- -- id, subid
and so on..
This is the plain design of the table. you know, like a table-id-field with a relation to another field within the table itself.
The Level isn't a part of the data.
"Level" is generated and attached to the dataset on collection of data, to sort out the different levels of deep.
id subid
-- id, subid
-- -- id, subid
-- -- -- id, subid
-- -- -- -- id, subid
and so on..
This is the plain design of the table. you know, like a table-id-field with a relation to another field within the table itself.
Sorry for the delay, had to grab something to eat.
Try this:
DaTribe
Try this:
DaTribe
protected void Page_Load(object sender, EventArgs e)
{
string nodeHtml = "<div class='fll'> <div class='tw1'>{0}</div><div class='tw2'>{1}</div> </div>";
List<SomeList> levels = new List<SomeList>();
TreeView tw = new TreeView();
levels
.Where(d => d.Level == 1)
.ToList()
.ForEach(sub =>
{
var node =
new TreeNode(string.Format(nodeHtml, sub.Username, sub.UserId.ToString(), String.Empty, sub.UserId));
Recursive(levels, nodeHtml, tw, 0, sub, node);
tw.Nodes.Add(node);
tw.CollapseAll();
});
}
void Recursive(IEnumerable<SomeList> levels, string nodeHtml, TreeView tw, int depth, SomeList item, TreeNode parentNode)
{
levels
.Where(d => d.subUserId == item.UserId)
.ToList()
.ForEach(sub =>
{
var node = new TreeNode(string.Format(nodeHtml, item.Username, item.UserId.ToString(), String.Empty, sub.UserId));
Recursive(levels, nodeHtml, tw, ++depth, sub, node);
tw.Nodes.Add(node);
if(depth < levels.Count())
parentNode.ChildNodes.Add(node);
});
}
A slight variation on the solution plus putting the CollapseAll outside the loop.
DaTribe
DaTribe
protected void Page_Load(object sender, EventArgs e)
{
string nodeHtml = "<div class='fll'> <div class='tw1'>{0}</div><div class='tw2'>{1}</div> </div>";
List<SomeList> levels = new List<SomeList>();
TreeView tw = new TreeView();
foreach (SomeList sub in levels.Where(d => d.Level == 1))
{
var node = new TreeNode(string.Format(nodeHtml, sub.Username, sub.UserId, String.Empty, sub.UserId));
Recursive(levels, nodeHtml, tw, 0, sub, node);
tw.Nodes.Add(node);
}
tw.CollapseAll();
}
void Recursive(IEnumerable<SomeList> levels, string nodeHtml, TreeView tw, int depth, SomeList item, TreeNode parentNode)
{
levels
.Where(d => d.subUserId == item.UserId)
.ToList()
.ForEach(sub =>
{
var node = new TreeNode(string.Format(nodeHtml, item.Username, item.UserId.ToString(), String.Empty, sub.UserId));
Recursive(levels, nodeHtml, tw, ++depth, sub, node);
tw.Nodes.Add(node);
if(depth < levels.Count())
parentNode.ChildNodes.Add(node);
});
}
ASKER
Thanks
though, try to skip the level-part.. :)
Level 1,2,3,4 are fictive, added data! I want the treeview to understand itself that there are no more nodes in
id,subid
and automatically understand to check next level of id,subid and add another node/items for that.
I can't think how to explain it better.. (except that I understand u still refer answers regarding to my original post)
though, try to skip the level-part.. :)
Level 1,2,3,4 are fictive, added data! I want the treeview to understand itself that there are no more nodes in
id,subid
and automatically understand to check next level of id,subid and add another node/items for that.
I can't think how to explain it better.. (except that I understand u still refer answers regarding to my original post)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
The more I look at this (it could just be that it is late in the day) is that the trigger that ends the recursive loop is incorrect and there is no accurate way to determine how to end.
// This seems to be incorrect
if(depth < levels.Count())
The simple question is, how do you determine you are at the maximum depth?
DaTribe
// This seems to be incorrect
if(depth < levels.Count())
The simple question is, how do you determine you are at the maximum depth?
DaTribe
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
tgerbert,
You stroked exactly into my point! Thank's a lot for that superplain and clean sample.
But because this was a side question, i split the points to you and daTribe.
Also I understand a little more that the treeview / recursive nodes way to think, isn't rocket science but still also not the simpliest of logic to achieve.
You stroked exactly into my point! Thank's a lot for that superplain and clean sample.
But because this was a side question, i split the points to you and daTribe.
Also I understand a little more that the treeview / recursive nodes way to think, isn't rocket science but still also not the simpliest of logic to achieve.
ASKER
This is EE when it's best,
DaTribe
Open in new window