你所拥有的是一个层次结构,无论何时你都可以考虑递归 - 一种调用自身的方法。您并不总是想使用递归,但对于可管理大小的列表或尾调用优化的递归方法,它是一个强大的工具。
这是输出的演示代码:
Category: 1, Hierarchy: Tools
Category: 2, Hierarchy: Tools/Hammer
Category: 3, Hierarchy: Tools/ScrewDriver
Category: 4, Hierarchy: Tools/ScrewDriver/Phillips
Category: 5, Hierarchy: Tools/ScrewDriver/Standard
Category: 6, Hierarchy: Tools/ScrewDriver/Phillips/#2
Category: 7, Hierarchy: Tools/ScrewDriver/Torx
Category: 8, Hierarchy: Tools/ScrewDriver/Torx/#15
(注意,我认为您的“0,工具”示例输出不正确)
这个程序会创建一个硬编码的ProductDef 列表。您的可能来自数据库或其他东西。
然后它会创建一个空的ProductHierarchy 列表,将在递归操作运行时填充该列表。
然后它通过第一次调用Build() 开始递归。在该方法中,当传入的项在层次结构中有父项时,它将调用自身。
当没有更多的父母时,它会将项目添加到ProductHierarchy的列表中。
void Main()
{
List<ProductDef> pdefs = new List<UserQuery.ProductDef>{
new ProductDef{Category = 1, Product = "Tools", ParentCategory = 0},
new ProductDef{Category = 2, Product = "Hammer", ParentCategory = 1},
new ProductDef{Category = 3, Product = "ScrewDriver", ParentCategory = 1},
new ProductDef{Category = 4, Product = "Phillips", ParentCategory = 3},
new ProductDef{Category = 5, Product = "Standard", ParentCategory = 3},
new ProductDef{Category = 6, Product = "#2", ParentCategory = 4},
new ProductDef{Category = 7, Product = "Torx", ParentCategory = 3},
new ProductDef{Category = 8, Product = "#15", ParentCategory = 7}
};
//This will get filled as we go
List<ProductHierarchy> phlist = new List<UserQuery.ProductHierarchy>();
//kick off the recursion
foreach (var element in pdefs)
{
Build(element, pdefs, element.Product, element.Category, phlist);
}
//do stuff with your list
foreach (ProductHierarchy ph in phlist)
{
Console.WriteLine(ph.ToString());
}
}
class ProductDef
{
public int Category { get; set; }
public string Product { get; set; }
public int ParentCategory { get; set; }
}
class ProductHierarchy
{
public int Category { get; set; }
public string Hierarchy { get; set; }
public override string ToString()
{
return $"Category: {Category}, Hierarchy: {Hierarchy}";
}
}
void Build(ProductDef def, List<ProductDef> lst, string fullname, int cat, List<ProductHierarchy> phlist)
{
string fullprodname = fullname;
//obtain the parent category of product
var parent = lst.FirstOrDefault(l => l.Category == def.ParentCategory);
if (parent != null)
{
fullprodname = $"{parent.Product}/{fullprodname}";
//recurse the call to see if the parent has any parents
Build(parent, lst, fullprodname, cat, phlist);
}
else
{
//No further parents found, add it to a list
phlist.Add( new ProductHierarchy { Category = cat, Hierarchy = fullprodname });
}
}