Let say we have a class
Category
{
ID,
Name,
ParentID
}
and a List
1, 'Item 1', 0
2, 'Item 2', 0
3, 'Item 3', 0
4, 'Item 1.1', 1
5, 'Item 3.1', 3
6, 'Item 1.1.1', 4
7, 'Item 2.1', 2
Can we using LINQ to render a tree like:
Item 1
Item 1.1
Item 1.1.1
Item 2
Item 2.1
Item 3
Item 3.1
Any help is appreciated!
Here's the "LINQ-only" version:
Func<int, int, string[]> build = null;
build = (p, n) =>
{
return (from x in categories
where x.ParentID == p
from y in new[]
{
"".PadLeft(n)+ x.Name
}.Union(build(x.ID, n + 1))
select y).ToArray();
};
var lines = build(0, 0);
Yes, it's recursive LINQ.
Per NVA
's request, here's the way to make all "orphan" records become root records:
Func<IEnumerable<int>, int, string[]> build = null;
build = (ps, n) =>
{
return (from x in categories
where ps.Contains(x.ParentID)
from y in new[]
{
"".PadLeft(n)+ x.Name
}.Union(build(new [] { x.ID }, n + 1))
select y).ToArray();
};
var roots = (from c in categories
join p in categories on c.ParentID equals p.ID into gps
where !gps.Any()
orderby c.ParentID
select c.ParentID).Distinct();
var lines = build(roots, 0);