簡體   English   中英

遍歷項目列表到其父級和父級到父級

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

我有一個要求遍歷具有 n 級層次結構的項目列表,並且我想獲取所選項目 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 參數,那么它應該打印 output 如下

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

如果我將 ID 參數作為 2 傳遞,那么 output 應該是相似的

ParentID=1, Name=Spices, Category=Breweries

請幫助我實現此功能可能是使用通用集合或任何算法都會有幫助

我嘗試過使用 List 並加上 LINQ 的 select 很多,但是使用此選項,我只能獲取當前項目,但如果當前項目沒有與之關聯的類別,則不能獲取父類別值。 還嘗試添加遞歸方法,但不確定如何構建結束 output,使用遞歸我們應該只獲取當前項目。

好的,根據以下評論,我使用了遞歸 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; }
}

但是,在一次迭代中,它返回父 ID 的類別,但由於它處於遞歸狀態,因此它繼續完成早期迭代的工作,因此此時類別始終返回“”(empty.string)

非遞歸解決方案可能如下所示:

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

沒有任何代碼,我只能為您的問題提供“默認”答案。

要解決您的問題,您必須在類中實現 function 以獲取實例的父級。

要獲得絕對父級(對象本身沒有父級),您必須實現一個 function,只要它有父級,它就會調用自己。

好的,終於讓它以正確的邏輯工作,工作代碼如下

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