[英]Create a Tree from a list of items, when each item contains a reference to its parent
[英]Create a nested list of items from objects with a parent reference
我正在使用C#
,我有一個具有可空父ID屬性的項目列表。
我需要將其轉換為具有子女列表的項目列表,並繼續下去,直到沒有項目為止。
我現有的課
public class Item
{
public int Id { get; set; }
public int? ParentId { get; set; }
}
我的第一個想法......
創建一個類
public class ItemWithChildren
{
public Item Item { get; set; }
public List<ItemWithChildren> Children { get; set; }
}
現在我需要一些方法來獲取List<ItemWithChildren>
,它將所有頂級Item對象及其子項放入Children
屬性中。
請注意,嵌套不是一組設定的級別。
我希望有一個優雅的LINQ查詢可以工作。 到目前為止我只有這個......
var itemsWithChildren = items.Select(a => new ItemWithChildren{ Item = a });
不使用純Linq執行此任務更具可讀性,但Linq和循環的混合使用。
給出以下容器:
class Node
{
public int Id { get; set; }
public int? ParentId { get; set; }
public List<Node> Children { get; set; }
}
然后,您可以使用以下代碼創建樹。
var nodes = new List<Node>
{
new Node{ Id = 1 },
new Node{ Id = 2 },
new Node{ Id = 3, ParentId = 1 },
new Node{ Id = 4, ParentId = 1 },
new Node{ Id = 5, ParentId = 3 }
};
foreach (var item in nodes)
{
item.Children = nodes.Where(x => x.ParentId.HasValue && x.ParentId == item.Id).ToList();
}
var tree = nodes.Where(x => !x.ParentId.HasValue).ToList();
這將處理任何級別的深度並返回正確的樹。
給定以下打印樹的方法:
private void PrintTree(IEnumerable<Node> nodes, int indent = 0)
{
foreach(var root in nodes)
{
Console.WriteLine(string.Format("{0}{1}", new String('-', indent), root.Id));
PrintTree(root.Children, indent + 1);
}
}
此調用的輸出是:
1
-3
--5
-4
2
但是,如果您想使用純Linq,可以執行以下操作,但對我來說,更難以閱讀:
var tree = nodes.Select(item =>
{
item.Children = nodes.Where(child => child.ParentId.HasValue && child.ParentId == item.Id).ToList();
return item;
})
.Where(item => !item.ParentId.HasValue)
.ToList();
這可能有幫助嗎?
var itemsWithChildren = items.Select(a => new ItemWithChildren{
Item = a,
Children = items.Where(b => b.ParentId==a.Id)
.ToList()
});
然后更新模型以實現它
public string Name { get; set; }
[DisplayName("Parent Category")]
public virtual Guid? CategoryUID { get; set; }
public virtual ICollection<Category> Categories { get; set; }
我認為你需要分兩步完成......我已經測試過它肯定有效......
var items = new List<Item>();
items.Add(new Item { Id = 1, ParentId = null });
items.Add(new Item { Id = 2, ParentId = 1 });
items.Add(new Item { Id = 3, ParentId = 1 });
items.Add(new Item { Id = 4, ParentId = 3 });
items.Add(new Item { Id = 5, ParentId = 3 });
var itemsWithChildren = items.Select(a =>
new ItemWithChildren { Item = a }).ToList();
itemsWithChildren.ForEach(a =>
a.Children = itemsWithChildren.Where(b =>
b.Item.ParentId == a.Item.Id).ToList());
var root = itemsWithChildren.Single(a => !a.Item.ParentId.HasValue);
Console.WriteLine(root.Item.Id);
Console.WriteLine(root.Children.Count);
Console.WriteLine(root.Children[0].Children.Count);
Console.WriteLine(root.Children[1].Children.Count);
輸出...
1 2 0 2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.