如何使用递归编程在列表框中填充多个类别
我有一个类别表,其设置允许无限数量的子类别级别。我想模仿以下内容:
需要澄清的是,子类别可以有子类别。例如,母猫 ->级别 1 -> 2级->级别 3 等。
我的类别表有两列,CategoryName
和 ParentID
。
将正确的类别分配给产品时将使用此列表框。
我该怎么写这个?
编辑
为了回应thedugas
,我必须修改你的答案以适应我的情况。我发现了一些需要修复的错误,但下面是最终的可行解决方案。
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);
}
}
}
这是即将完成的作品:
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:
It should be clarified that sub categories can have sub categories. E.g. Parent cat -> level 1 -> level 2 -> level 3 etc.
My categories table has two columns, CategoryName
and ParentID
.
This list box will be used when assigning the correct category to a product.
How can I write this?
Edit
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:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尼克在评论中问我 另一个问题如何使用 LINQ to Objects 解决此类问题而不使用任何递归。轻松完成。
假设我们有一个将 id 映射到类别的
Dictionary
。每个类别都有三个字段:Id、ParentId 和 Name。我们假设 ParentId 可以为 null,以标记那些“顶级”类别。所需的输出是字符串序列,其中每个字符串都是类别的“完全限定”名称。
解决方案很简单。我们首先定义一个辅助方法:
并且这个辅助方法:
或者,如果您希望避免可能效率低下的朴素字符串连接:
现在查询很简单:
不需要递归。
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.
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:
And this helper method:
Or, if you prefer avoiding the potentially inefficient naive string concatenation:
And now the query is straightforward:
No recursion necessary.
如果可以的话,我想说在 SQL 中使用递归 CTE。
编辑:这是 MS SQL >= 2005 的递归 CTE:
如果你不能,那么这是一种方法:
I would say to use a recursive CTE in SQL if you can.
Edit: here is a recursive CTE for MS SQL >= 2005:
If you can't then here is one way:
假设顶级类别的 ParentID 将为 NULL。
我会选择:
dataset1
string MainCategory as string="";
Assuming the ParentID will be NULL for the Top Category.
I would go for:
dataset1
string MainCategory as string="";