我怎样才能用递归编程填充列表框与多个类别 [英] How can I populate a list box with many categories using recursive programming

查看:97
本文介绍了我怎样才能用递归编程填充列表框与多个类别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有被设置为允许分类别等级的无限数量的类别表。我想模仿如下:

I have a categories table which is set up to allow an infinite number of sub category levels. I would like to mimic the following:

这应该澄清,子类可以有子类。例如。家长猫 - > 1级 - > 2级 - > 3级等

It should be clarified that sub categories can have sub categories. E.g. Parent cat -> level 1 -> level 2 -> level 3 etc.

我的类别表有两列,类别名称 PARENTID

My categories table has two columns, CategoryName and ParentID.

此列表框将分配正确的类别产品时使用。

This list box will be used when assigning the correct category to a product.

我怎么可以这样写?

修改

在回应 thedugas 我不得不修改你的答案跟我的情况的工作。我发现,需要一些错误是固定的,但低于是最终的,工作的解决方案。

In response to thedugas I had to modify your answer to work with my situation. I found some errors that needed to be fixed, but below is a final, working solution.

protected void Page_Load(object sender, EventArgs e)
    {
        using (DataClasses1DataContext db = new DataClasses1DataContext())
        {

        var c = db.Categories.Select(x => x);

        List<Category> categories = new List<Category>();
        foreach (var n in c)
        {
            categories.Add(new Category()
            {
                categoryID = n.categoryID,
                title = n.title,
                parentID = n.parentID,
                isVisible = n.isVisible
            });
        }
        List<string> xx = new List<string>();

        foreach (Category cat in categories)
        {
            BuildCatString(string.Empty, cat, categories, xx);
        }

        ListBox1.DataSource = xx;
        ListBox1.DataBind();

    }
}

private void BuildCatString(string prefix, Category cat, IEnumerable<Category> categories, List<string> xx)
{
    if (cat.parentID == 0)
    {
        xx.Add(cat.title);
        prefix = cat.title;
    }

    var children = categories.Where(x => x.parentID == cat.categoryID);
    if (children.Count() == 0)
    {
        return;
    }

    foreach (Category child in children)
    {
        if(prefix.Any())
        {
        xx.Add(prefix + "/" + child.title);
        BuildCatString(prefix + "/" + child.title,
            child, categories, xx);
        }
    }

}

下面是几乎完成的工作:

Here is the almost finished work:

推荐答案

尼克问我在一个注释<一个href=\"http://stackoverflow.com/questions/4073713/is-there-a-good-linq-way-to-do-a-cartesian-product/4073806#4073806\">another 的问题怎么这样的问题可能使用LINQ to对象,而无需使用任何递归来解决。轻松完成。

Nick asked me in a comment to another question how this sort of problem might be solved using LINQ to Objects without using any recursion. Easily done.

让我们假设我们有一个词典&LT;编号,类别&GT; 映射IDS类别。每个类别有三个字段:ID,和的ParentId名称。让我们presume说的ParentId可以为空,以纪念那些顶级。

Let's suppose that we have a Dictionary<Id, Category> that maps ids to categories. Each category has three fields: Id, ParentId and Name. Let's presume that ParentId can be null, to mark those categories that are "top level".

所需的输出是一个字符串的序列,其中每个字符串是该类别的完全合格的名字。

The desired output is a sequence of strings where each string is the "fully-qualified" name of the category.

解决的办法很简单。我们首先定义一个辅助方法:

The solution is straightforward. We begin by defining a helper method:

public static IEnumerable<Category> CategoryAndParents(this Dictionary<Id, Category> map, Id id)
{
    Id current = id;
    while(current != null)
    {
        Category category = map[current];
        yield return category;
        current = category.ParentId;
    }
}

和这个辅助方法:

public static string FullName(this Dictionary<Id, Category> map, Id id)
{
    return map.CategoryAndParents(id)
              .Aggregate("", (string name, Category cat) =>
                cat.Name + (name == "" ? "" : @"/") + name);
}

或者,如果你preFER避免潜在的低效天真字符串连接:

Or, if you prefer avoiding the potentially inefficient naive string concatenation:

public static string FullName(this Dictionary<Id, Category> map, Id id)
{
    return string.Join(@"/", map.CategoryAndParents(id)
                                .Select(cat=>cat.Name)
                                .Reverse());
}

而现在的查询是简单的:

And now the query is straightforward:

fullNames = from id in map.Keys
            select map.FullName(id);
listBox.DataSource = fullNames.ToList();

没有必要递归。

这篇关于我怎样才能用递归编程填充列表框与多个类别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆