简体   繁体   English

遍历项目列表到其父级和父级到父级

[英]Iterate through list of items to their parent and parent to parent level

I have one requirement to iterate through list of items which has n-level of hierarchy and I would like to get bottom-up elements for the selected item ID.我有一个要求遍历具有 n 级层次结构的项目列表,并且我想获取所选项目 ID 的自下而上元素。

For eg below is the raw data例如,下面是原始数据

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         

I want to program in C# to iterate and show for eg if I pass ID parameter for method 6 then it should print output as below我想在 C# 中编程以进行迭代并显示例如,如果我为方法 6 传递 ID 参数,那么它应该打印 output 如下

ParentID=3, Name=My Tax, Category=Taxes

If I pass ID parameter as 2 then output should be similar如果我将 ID 参数作为 2 传递,那么 output 应该是相似的

ParentID=1, Name=Spices, Category=Breweries

please help me in achieving this functionality may be by using Generic collection or any algorithm would help请帮助我实现此功能可能是使用通用集合或任何算法都会有帮助

What I have tried is I have tried using List and plus LINQ's select many, but with this option I was able to fetch only current item, but not parent category value if current item do not have category associated to it.我尝试过使用 List 并加上 LINQ 的 select 很多,但是使用此选项,我只能获取当前项目,但如果当前项目没有与之关联的类别,则不能获取父类别值。 Also tried to add recursive method but not sure how to build end output, with recursive we should only get current item.还尝试添加递归方法,但不确定如何构建结束 output,使用递归我们应该只获取当前项目。

Okay as per below comments I have used recursive function as below好的,根据以下评论,我使用了递归 function 如下

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; }
}

However, in one iteration it returns Category for parentID, but as it's in recursion it keep on finish its job for earlier iteration hence at this point Category is all time returns ""(empty.string)但是,在一次迭代中,它返回父 ID 的类别,但由于它处于递归状态,因此它继续完成早期迭代的工作,因此此时类别始终返回“”(empty.string)

Non-recursive solution can look like this:非递归解决方案可能如下所示:

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}");

Without any code, I can only give you a "default" answer for your problem.没有任何代码,我只能为您的问题提供“默认”答案。

To solve your problem, you must implement a function in your classes to get the parent of your instance.要解决您的问题,您必须在类中实现 function 以获取实例的父级。

To get the absolute parent (object has no parent itself) you must implement a function which calls itself as long as it has a parent.要获得绝对父级(对象本身没有父级),您必须实现一个 function,只要它有父级,它就会调用自己。

Ok finally got it working with correct logic, working code as below好的,终于让它以正确的逻辑工作,工作代码如下

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; }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM