首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >迭代项目列表到它们的父级和父级

迭代项目列表到它们的父级和父级
EN

Stack Overflow用户
提问于 2021-04-21 18:35:15
回答 3查看 66关注 0票数 0

我有一个需求是迭代遍历具有n级层次结构的项目列表,并且我希望为选定的项目ID获取自下而上的元素。

例如,下面是原始数据

代码语言:javascript
复制
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参数,那么它应该打印输出,如下所示

代码语言:javascript
复制
ParentID=3, Name=My Tax, Category=Taxes

如果我将ID参数作为2传递,则输出应该类似

代码语言:javascript
复制
ParentID=1, Name=Spices, Category=Breweries

请帮助我实现此功能可能是通过使用泛型集合或任何算法都会有所帮助

我尝试过的是,我尝试使用List和加上LINQ的select have,但是使用这个选项,我只能获取当前项,但如果当前项没有与其关联的类别,则无法获取父类别值。也尝试添加递归方法,但不确定如何构建最终输出,对于递归,我们应该只获取当前项。

好的,根据下面的评论,我已经使用了如下递归函数

代码语言:javascript
复制
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; }
}

然而,在一次迭代中,它返回Category for parentID,但由于它在递归中,它会继续完成较早迭代的工作,因此在这一点上,Category is all time return ""(empty.string)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-04-21 23:19:05

Ok最终让它与正确的逻辑一起工作,工作代码如下

代码语言:javascript
复制
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; }
}
票数 0
EN

Stack Overflow用户

发布于 2021-04-22 01:34:35

非递归解决方案可能如下所示:

代码语言:javascript
复制
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}");
票数 1
EN

Stack Overflow用户

发布于 2021-04-21 18:42:44

没有任何代码,我只能为您的问题给出一个“默认”答案。

要解决您的问题,必须在类中实现一个函数来获取实例的父级。

要获得绝对父对象(对象本身没有父对象),必须实现一个函数,该函数只要有父对象就会调用它自己。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67194124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档