嘿所有人,我精神上被困住了
我有一个从Web API检索到的对象列表,其中包含三个值,包括父ID,字符串值和行ID
IE:
CategoryID名称ParentID
1工具0
2 Hammer 1
3 ScrewDriver 1
4 Phillips 3
5标准3
6#2 4
7 Torx 3
8#15 7
等
这需要放入一个简单的列表对象,该对象由ParentID和直接类别名称和父ID的串联字符串组成
CategoryID FullCategoryName
0工具
2工具/锤子
3工具/ ScrewDriver
4工具/ ScrewDriver / Phillips
5工具/ ScrewDriver /标准
6工具/ ScrewDriver / Phillips /#2
7工具/ ScrewDriver / Torx
8工具/ ScrewDriver / Torx /#15
我希望你能够看到我需要classID和基于父ID的完整路径斜杠。
API Called Class
public class Categories_Web
{
public string CategoryName { get; set; }
public int CategoryParent { get; set; }
public int CategoryID { get; set; }
}
带有连接名称的简化类
public class WebCategoriesSimple
{
public int CategoryID { get; set; }
public string CategoryName { get; set; }
}
我希望这是有道理的,谢谢你的帮助!
答案 0 :(得分:1)
你所拥有的是一个层次结构,只要你拥有它,就可以考虑递归 - 一种自我调用的方法。您并不总是希望使用递归,但对于可管理大小的列表或尾调用优化的递归方法,它是一个强大的工具。
以下是输出的演示代码:
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 });
}
}
答案 1 :(得分:0)
这是我认为LINQ非常适合的问题之一。我在理解数据格式方面遇到了一些麻烦。但是,您可以使用LINQ投影将原始列表的结果投影到包含基于类定义的新对象或新匿名类的新列表中。
使用LINQ投影到一个新的匿名类,看起来如下所示。请注意,我们不知道您的对象名称,因为您没有提供该信息,因此您可能需要从我的示例中进行一些推断。
(请注意,我重读了您的帖子,我想我了解您的原始对象可能会被调用,因此该帖子已经过编辑以使用您的班级名称。)
var newListOfStuff = originalListOfStuff.Select(s => new {
CategoryID = s.CategoryID,
CategoryName = $"Tools/{s.CategoryName}/#{s.CategoryParent}"
});
使用字符串插值创建字符串,这在C#中是新的。如果您的C#版本不支持,您可以使用string.Format,如下所示:
string.Format("Tools/{0}/#{1}", s.CategoryName, s.CategoryParent);
使用这个新列表,您可以遍历它并使用如下属性:
foreach(var item in newListOfStuff)
{
Console.WriteLine(item.CategoryID);
Console.WriteLine(item.CategoryName);
}
这是一个类似的参考答案: https://stackoverflow.com/a/9885766/3096683