public class Hierarchy
{
public int Id { set; get; }
public int? ParentId { set; get; }
public int Level { set; get; }
}
class Program
{
public static List<Hierarchy> GetData()
{
List<Hierarchy> hierarchies = new List<Hierarchy>()
{
new Hierarchy(){ Id = 1 , ParentId= null, Level = 0 },
new Hierarchy(){ Id = 2 , ParentId= 1 , Level = 1},
new Hierarchy(){ Id = 3 , ParentId= 1, Level = 1 },
new Hierarchy(){ Id = 4 , ParentId= 2, Level = 2 },
new Hierarchy(){ Id = 5 , ParentId= 2, Level = 2 },
new Hierarchy(){ Id = 6 , ParentId= 3, Level = 2 },
new Hierarchy(){ Id = 7 , ParentId= 3, Level = 2 },
new Hierarchy(){ Id = 8 , ParentId= 4, Level = 3 },
};
return hierarchies;
}
public static List<Hierarchy> GetTree(List<int> Ids, List<Hierarchy> hierarchies)
{
foreach (var item in Ids)
{
var result = GetData().Where(x => x.ParentId == item).Select(x => x.Id).ToList();
Hierarchy hierarchy = new Hierarchy();
hierarchy.Id = item;
hierarchy.ParentId = GetData().FirstOrDefault(x => x.Id == hierarchy.Id).ParentId;
hierarchy.Level = GetData().FirstOrDefault(x => x.Id == hierarchy.Id).Level;
hierarchies.Add(hierarchy);
GetTree(result, hierarchies);
}
return hierarchies;
}
static void Main(string[] args)
{
List<int> Ids = new List<int>();
Ids.Add(1);
List<Hierarchy> hierarchies = new List<Hierarchy>();
GetTree(Ids, hierarchies);
foreach (var item in hierarchies)
{
Console.WriteLine(item.Id);
}
}
}
I need to get Hierarchical data for report printing I need to traverse through each node from top to bottom and again from top to bottom
tried and getting 1 -> 2 -> 4 -> 8 -> 5 - > 3 -> 6 -> 7
expected output 1 -> 2 -> 4 - > 5 -> 8 then again from top 1 -> 3 - > 6 - > 7 in a single collection
I tried to write recursive function and it give me data through all node but it does not match with my requirement
CodePudding user response:
The output cannot be a List<Hierarchy>
is you want each path from top to bottom. What you need is a List<List<Hierarchy>>
.
Here's are the pair of functions that do it.
public static List<List<Hierarchy>> GetTree(ILookup<int?, Hierarchy> lookup) =>
GetTree(lookup, null);
private static List<List<Hierarchy>> GetTree(ILookup<int?, Hierarchy> lookup, int? parent)
{
var output = new List<List<Hierarchy>>();
var children = lookup[parent];
foreach (var child in children)
{
var grandchildren = GetTree(lookup, child.Id);
if (grandchildren.Any())
{
foreach (var grandchild in grandchildren)
{
output.Add(grandchild.StartWith(child).ToList());
}
}
else
{
output.Add(new List<Hierarchy>() { child });
}
}
return output;
}
The ILookup<int?, Hierarchy> lookup
is a LINQ interface that allows to to produce an IEnumberable<Hierarchy>
for any ParentId
passed in.
GetTree(ILookup<int?, Hierarchy> lookup, int? parent)
recursively runs down the tree when it finds a child has grandchildren and when a child doesn't it returns just that child. It then builds each list as it recurses back up the call stack.
When I run this code:
List<Hierarchy> data = GetData();
ILookup<int?, Hierarchy> lookup = data.ToLookup(x => x.ParentId);
List<List<Hierarchy>> result = GetTree(lookup);
foreach (List<Hierarchy> rs in result)
{
Console.WriteLine(String.Join(" -> ", rs.Select(r => r.Id)));
}
I get out this:
1 -> 2 -> 4 -> 8
1 -> 2 -> 5
1 -> 3 -> 6
1 -> 3 -> 7
CodePudding user response:
public class Hierarchy
{
public Hierarchy()
{
Children = new List<Hierarchy>();
}
public int Id { set; get; }
public int? ParentId { set; get; }
public int Level { set; get; }
public List<Hierarchy> Children { set; get; }
}
class Program
{
public static List<Hierarchy> GetData()
{
List<Hierarchy> hierarchies = new List<Hierarchy>()
{
new Hierarchy(){ Id = 1 , ParentId= null, Level = 0 },
new Hierarchy(){ Id = 2 , ParentId= 1 , Level = 1},
new Hierarchy(){ Id = 3 , ParentId= 1, Level = 1 },
new Hierarchy(){ Id = 4 , ParentId= 2, Level = 2 },
new Hierarchy(){ Id = 5 , ParentId= 2, Level = 2 },
new Hierarchy(){ Id = 6 , ParentId= 3, Level = 2 },
new Hierarchy(){ Id = 7 , ParentId= 3, Level = 2 },
new Hierarchy(){ Id = 8 , ParentId= 4, Level = 3 },
new Hierarchy(){ Id = 9 , ParentId= 5, Level = 3 },
new Hierarchy(){ Id = 10 , ParentId= 7, Level = 3 },
};
return hierarchies;
}
public static IEnumerable<Hierarchy> GetNodes(Hierarchy node)
{
if (node == null)
{
yield
break;
}
yield
return node;
foreach (var n in node.Children)
{
foreach (var innerN in GetNodes(n))
{
yield
return innerN;
}
}
}
public static List<Hierarchy> GethierarchicalTree(int? parentId = null)
{
var all = GetData();
return all.Where(c => c.ParentId == parentId)
.Select(c => new Hierarchy()
{
Id = c.Id,
Level = c.Level,
ParentId = c.ParentId,
Children = GetChildren(all, c.Id)
})
.ToList();
}
public static List<Hierarchy> GetChildren(List<Hierarchy> hierarchies, int parentId)
{
return hierarchies.Where(c => c.ParentId == parentId)
.Select(c => new Hierarchy
{
Id = c.Id,
ParentId = c.ParentId,
Level = c.Level,
Children = GetChildren(hierarchies, c.Id)
})
.ToList();
}
static void Main(string[] args)
{
var re = GethierarchicalTree(1);
var parent = GetData().FirstOrDefault(x => x.ParentId == null);
List<Hierarchy> lst = new List<Hierarchy>();
foreach (var item in re)
{
var rxt = GetNodes(item).OrderBy(x => x.Level).ToList();
lst.Add(parent);
lst.AddRange(rxt);
}
foreach (var item in lst)
{
Console.WriteLine("Id :" item.Id " Parent :" item.ParentId);
}
}
}
thanks for your help I have figured it out by myself