使用父ID C#将平面列表映射到分层列表

Ben*_*Ben 8 c#

我有一个类别的平面列表,如以下类所示

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)

Mar*_*zek 6

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)

  • 这里根本不需要`if(lookup.Contains(c.ID))`.实际上,它可能是有害的,因为如果一个节点没有子节点,那么对于子集合来说,将空列表设置为"null"会更好. (3认同)

Ser*_*rvy 5

进行此转换的一种非常简单且高性能的方法是创建一个查找,在该查找中,您将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)