我有一个类别的平面列表,如以下类所示
public class FlatCategoryList
{
public List<FlatCategory> Categories { get; set; }
}
public class FlatCategory
{
public string ID { get; set; }
public string Name { get; set; }
public string ParentID { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试将我的平面类别列表映射到一个层次结构,如下所示:
public class HieraricalCategoryList
{
public List<Category> Categories { get; set; }
}
public class Category
{
public string ID { get; set; }
public string Name { get; set; }
public string ParentID { get; set; }
public List<Category> ChildCategories { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,实现这一目标的最佳方法是什么,因为可能存在无限数量的子层?
public HieraricalCategoryList MapCategories(FlatCategoryList flatCategoryList)
{
var hieraricalCategoryList = new HieraricalCategoryList();
//Do something here to map the flat category list to the hierarichal one...
return hieraricalCategoryList;
}
Run Code Online (Sandbox Code Playgroud)
public HieraricalCategoryList MapCategories(FlatCategoryList flatCategoryList)
{
var categories = (from fc in flatCategoryList.Categories
select new Category() {
ID = fc.ID,
Name = fc.Name,
ParentID = fc.ParentID
}).ToList();
var lookup = categories.ToLookup(c => c.ParentID);
foreach(var c in categories)
{
// you can skip the check if you want an empty list instead of null
// when there is no children
if(lookup.Contains(c.ID))
c.ChildCategories = lookup[c.ID].ToList();
}
return new HieraricalCategoryList() { Categories = categories };
}
Run Code Online (Sandbox Code Playgroud)
进行此转换的一种非常简单且高性能的方法是创建一个查找,在该查找中,您将ID值映射到应该是该ID值的子级的节点。可以在节点的一次通过中创建此查找。之后,您可以遍历所有节点,再次将其子集合分配为查找中其ID值的值。
请注意,如果查询映射到您要转换成的类型而不是转换成的对象,这将更简单。
var lookup = list.Categories
.Select(category => new Category()
{
ID = category.ID,
Name = category.Name,
ParentID = category.ParentID,
})
.ToLookup(category => category.ParentID);
foreach (var category in lookup.SelectMany(x => x))
category.ChildCategories = lookup[category.ID].ToList();
var newList = new HieraricalCategoryList()
{
Categories = lookup[null].ToList(),
};
Run Code Online (Sandbox Code Playgroud)