尼克在评论中问我另一个问题 https://stackoverflow.com/questions/4073713/is-there-a-good-linq-way-to-do-a-cartesian-product/4073806#4073806如何使用 LINQ to Objects 解决此类问题而不使用任何递归。轻松完成。
假设我们有一个Dictionary<Id, Category>
将 id 映射到类别。每个类别都有三个字段:Id、ParentId 和 Name。我们假设 ParentId 可以为 null,以标记那些“顶级”类别。
所需的输出是字符串序列,其中每个字符串都是类别的“完全限定”名称。
解决方案很简单。我们首先定义一个辅助方法:
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);
}
或者,如果您希望避免可能效率低下的朴素字符串连接:
public static string FullName(this Dictionary<Id, Category> map, Id id)
{
return string.Join(@"/", map.CategoryAndParents(id)
.Select(cat=>cat.Name)
.Reverse());
}
现在查询很简单:
fullNames = from id in map.Keys
select map.FullName(id);
listBox.DataSource = fullNames.ToList();
无需递归。