【发布时间】:2011-01-02 00:10:05
【问题描述】:
不知道怎么称呼它,但是说你有一个看起来像这样的类:
class Person
{
public string Name;
public IEnumerable<Person> Friends;
}
然后你有一个人,你想递归地“展开”这个结构,所以你最终得到一个没有重复的人的单一列表。
你会怎么做?我已经做了一些似乎可以工作的东西,但我很想看看其他人会怎么做,特别是如果 Linq 有内置的东西,你可以用一种聪明的方式来解决这个小问题:)
这是我的解决方案:
public static IEnumerable<T> SelectRecursive<T>(this IEnumerable<T> subjects, Func<T, IEnumerable<T>> selector)
{
// Stop if subjects are null or empty
if(subjects == null)
yield break;
// For each subject
foreach(var subject in subjects)
{
// Yield it
yield return subject;
// Then yield all its decendants
foreach (var decendant in SelectRecursive(selector(subject), selector))
yield return decendant;
}
}
会像这样使用:
var people = somePerson.SelectRecursive(x => x.Friends);
【问题讨论】:
-
我遗漏了一些东西......如果你在那里有循环,它会停止吗?
-
@Kobi:这是由
if(!subjects.Any()) yield break;完成的 -
@Oliver:不,不会。只有在主题列表为空时才会停止。所以我想我实际上可以完全跳过那部分,因为它不会有任何区别......
-
@Kobi:不,你没有遗漏任何东西。它永远不会停止 :p 当我制作它时我正在使用的东西永远不会有任何循环,所以没有费心做任何事情。如果需要,我可能会使用 HashSet 来跟踪我已经访问过的主题。
-
删除了 !subjects.Any() 部分,因为它并没有真正起到任何作用,只是让人困惑:p
标签: c# recursion ienumerable