遍历项目列表到它们的父级和父级到父级
Iterate through list of items to their parent and parent to parent level
我有一个要求遍历具有 n 级层次结构的项目列表,我想为 selected 项目 ID 获取自下而上的元素。
例如以下是原始数据
ID ParentID ItemName Category
1 -1 Chai Breweries
4 -1 Mouse-pad Electronic
3 1 GST Taxes
2 1 Spices
5 4 Mobile
6 3 My Tax
我想用 C# 编程来迭代和显示,例如如果我为方法 6 传递 ID 参数,那么它应该如下打印输出
ParentID=3, Name=My Tax, Category=Taxes
如果我将 ID 参数作为 2 传递,则输出应该类似
ParentID=1, Name=Spices, Category=Breweries
请帮助我实现此功能可能是通过使用通用集合或任何算法都会有所帮助
我试过的是
我尝试过使用 List 和 plus LINQ 的 select 很多,但是使用这个选项我只能获取当前项目,但如果当前项目没有与之关联的类别,则不能获取父类别值。
还尝试添加递归方法但不确定如何构建最终输出,使用递归我们应该只获取当前项目。
好的,按照下面的评论,我使用了如下的递归函数
class Program
{
static void Main(string[] args)
{
int categoryId = 202;
var products = GetProducts();
var product = products.FirstOrDefault(p => p.ID == categoryId);
var output = GetProductRecursively(products, categoryId, string.Empty);
Console.WriteLine(output);
Console.Read();
}
public static string GetProductRecursively(List<Product> products, int parentId, string output)
{
var product = products.FirstOrDefault(p => p.ParentID == parentId);
StringBuilder stringBuilder = new StringBuilder();
if (string.IsNullOrEmpty(product.Category))
{
if (string.IsNullOrEmpty(output))
{
stringBuilder.Append($"ParentCategoryID={ product.ParentID}, Name={ product.ItemName}, Keywords=");
GetProductRecursively(products, product.ParentID, stringBuilder.ToString());
}
else
GetProductRecursively(products, product.ParentID, output);
}
else
stringBuilder.Append($"{output}{product.Category}");
return stringBuilder.ToString();
}
public static List<Product> GetProducts()
{
var products = new List<Product>();
products.Add(new Product { ID = 1, ParentID = -1, ItemName = "Chai", Category = "Breweries" });
products.Add(new Product { ID = 4, ParentID = -1, ItemName = "Mouse-pad", Category= "Electronic" });
products.Add(new Product { ID = 3, ParentID = 1, ItemName = "GST", Category= "Taxes" });
products.Add(new Product { ID = 2, ParentID = 1, ItemName = "Spices" });
products.Add(new Product { ID = 5, ParentID = 4, ItemName = "Mobile" });
products.Add(new Product { ID = 6, ParentID = 3, ItemName = "My Tax" });
return products;
}
}
public class Product
{
public int ID { get; set; }
public int ParentID { get; set; }
public string ItemName { get; set; }
public string Category { get; set; }
}
然而,在一次迭代中,它 returns parentID 的类别,但由于它是递归的,它会继续完成早期迭代的工作,因此此时类别一直是 returns ""( empty.string)
没有任何代码,我只能给你一个“默认”的答案。
要解决您的问题,您必须在 类 中实现一个函数来获取实例的父级。
要获得绝对父对象(对象本身没有父对象),您必须实现一个函数,只要它有父对象就会调用自身。
好吧,终于让它以正确的逻辑工作,工作代码如下
class Program
{
static void Main(string[] args)
{
int productId = 6;
var products = GetProducts();
var product = products.FirstOrDefault(p => p.ID == productId);
var output = GetProductRecursively(products, productId, string.Empty);
Console.WriteLine(output);
Console.Read();
}
public static string GetProductRecursively(List<Product> products, int Id, string output)
{
var product = products.FirstOrDefault(p => p.ID == Id);
StringBuilder stringBuilder = new StringBuilder();
if (string.IsNullOrEmpty(output))
output = stringBuilder.Append($"ParentCategoryID={ product.ParentID}, Name={ product.ItemName}, Keywords=").ToString();
if (string.IsNullOrEmpty(product.Category))
{
return GetProductRecursively(products, product.ParentID, output);
}
else
output += $"{product.Category}";
return output;
}
public static List<Product> GetProducts()
{
var products = new List<Product>();
products.Add(new Product { ID = 1, ParentID = -1, ItemName = "Chai", Category = "Breweries" });
products.Add(new Product { ID = 4, ParentID = -1, ItemName = "Mouse-pad", Category = "Electronic" });
products.Add(new Product { ID = 3, ParentID = 1, ItemName = "GST", Category = "Taxes" });
products.Add(new Product { ID = 2, ParentID = 1, ItemName = "Spices" });
products.Add(new Product { ID = 5, ParentID = 4, ItemName = "Mobile" });
products.Add(new Product { ID = 6, ParentID = 3, ItemName = "My Tax" });
return products;
}
}
public class Product
{
public int ID { get; set; }
public int ParentID { get; set; }
public string ItemName { get; set; }
public string Category { get; set; }
}
非递归解决方案如下所示:
var productId = 6;
var products = GetProducts();
var productDict = products // create dictionary to search for products by id
.GroupBy(p => p.ID)
.ToDictionary(p => p.Key, g => g.First());
var product = productDict[productId];
// create loop state variables
string category = null;
var currProduct = product;
// cycle while category not found
while (category == null)
{
// or there is no parent product
if (!productDict.ContainsKey(currProduct.ParentID))
{
break;
}
currProduct = productDict[currProduct.ParentID];
category = currProduct.Category;
}
Console.WriteLine($"{category}-{product.ItemName}");
我有一个要求遍历具有 n 级层次结构的项目列表,我想为 selected 项目 ID 获取自下而上的元素。
例如以下是原始数据
ID ParentID ItemName Category
1 -1 Chai Breweries
4 -1 Mouse-pad Electronic
3 1 GST Taxes
2 1 Spices
5 4 Mobile
6 3 My Tax
我想用 C# 编程来迭代和显示,例如如果我为方法 6 传递 ID 参数,那么它应该如下打印输出
ParentID=3, Name=My Tax, Category=Taxes
如果我将 ID 参数作为 2 传递,则输出应该类似
ParentID=1, Name=Spices, Category=Breweries
请帮助我实现此功能可能是通过使用通用集合或任何算法都会有所帮助
我试过的是 我尝试过使用 List 和 plus LINQ 的 select 很多,但是使用这个选项我只能获取当前项目,但如果当前项目没有与之关联的类别,则不能获取父类别值。 还尝试添加递归方法但不确定如何构建最终输出,使用递归我们应该只获取当前项目。
好的,按照下面的评论,我使用了如下的递归函数
class Program
{
static void Main(string[] args)
{
int categoryId = 202;
var products = GetProducts();
var product = products.FirstOrDefault(p => p.ID == categoryId);
var output = GetProductRecursively(products, categoryId, string.Empty);
Console.WriteLine(output);
Console.Read();
}
public static string GetProductRecursively(List<Product> products, int parentId, string output)
{
var product = products.FirstOrDefault(p => p.ParentID == parentId);
StringBuilder stringBuilder = new StringBuilder();
if (string.IsNullOrEmpty(product.Category))
{
if (string.IsNullOrEmpty(output))
{
stringBuilder.Append($"ParentCategoryID={ product.ParentID}, Name={ product.ItemName}, Keywords=");
GetProductRecursively(products, product.ParentID, stringBuilder.ToString());
}
else
GetProductRecursively(products, product.ParentID, output);
}
else
stringBuilder.Append($"{output}{product.Category}");
return stringBuilder.ToString();
}
public static List<Product> GetProducts()
{
var products = new List<Product>();
products.Add(new Product { ID = 1, ParentID = -1, ItemName = "Chai", Category = "Breweries" });
products.Add(new Product { ID = 4, ParentID = -1, ItemName = "Mouse-pad", Category= "Electronic" });
products.Add(new Product { ID = 3, ParentID = 1, ItemName = "GST", Category= "Taxes" });
products.Add(new Product { ID = 2, ParentID = 1, ItemName = "Spices" });
products.Add(new Product { ID = 5, ParentID = 4, ItemName = "Mobile" });
products.Add(new Product { ID = 6, ParentID = 3, ItemName = "My Tax" });
return products;
}
}
public class Product
{
public int ID { get; set; }
public int ParentID { get; set; }
public string ItemName { get; set; }
public string Category { get; set; }
}
然而,在一次迭代中,它 returns parentID 的类别,但由于它是递归的,它会继续完成早期迭代的工作,因此此时类别一直是 returns ""( empty.string)
没有任何代码,我只能给你一个“默认”的答案。
要解决您的问题,您必须在 类 中实现一个函数来获取实例的父级。
要获得绝对父对象(对象本身没有父对象),您必须实现一个函数,只要它有父对象就会调用自身。
好吧,终于让它以正确的逻辑工作,工作代码如下
class Program
{
static void Main(string[] args)
{
int productId = 6;
var products = GetProducts();
var product = products.FirstOrDefault(p => p.ID == productId);
var output = GetProductRecursively(products, productId, string.Empty);
Console.WriteLine(output);
Console.Read();
}
public static string GetProductRecursively(List<Product> products, int Id, string output)
{
var product = products.FirstOrDefault(p => p.ID == Id);
StringBuilder stringBuilder = new StringBuilder();
if (string.IsNullOrEmpty(output))
output = stringBuilder.Append($"ParentCategoryID={ product.ParentID}, Name={ product.ItemName}, Keywords=").ToString();
if (string.IsNullOrEmpty(product.Category))
{
return GetProductRecursively(products, product.ParentID, output);
}
else
output += $"{product.Category}";
return output;
}
public static List<Product> GetProducts()
{
var products = new List<Product>();
products.Add(new Product { ID = 1, ParentID = -1, ItemName = "Chai", Category = "Breweries" });
products.Add(new Product { ID = 4, ParentID = -1, ItemName = "Mouse-pad", Category = "Electronic" });
products.Add(new Product { ID = 3, ParentID = 1, ItemName = "GST", Category = "Taxes" });
products.Add(new Product { ID = 2, ParentID = 1, ItemName = "Spices" });
products.Add(new Product { ID = 5, ParentID = 4, ItemName = "Mobile" });
products.Add(new Product { ID = 6, ParentID = 3, ItemName = "My Tax" });
return products;
}
}
public class Product
{
public int ID { get; set; }
public int ParentID { get; set; }
public string ItemName { get; set; }
public string Category { get; set; }
}
非递归解决方案如下所示:
var productId = 6;
var products = GetProducts();
var productDict = products // create dictionary to search for products by id
.GroupBy(p => p.ID)
.ToDictionary(p => p.Key, g => g.First());
var product = productDict[productId];
// create loop state variables
string category = null;
var currProduct = product;
// cycle while category not found
while (category == null)
{
// or there is no parent product
if (!productDict.ContainsKey(currProduct.ParentID))
{
break;
}
currProduct = productDict[currProduct.ParentID];
category = currProduct.Category;
}
Console.WriteLine($"{category}-{product.ItemName}");