遍历 "tree" 动态给定的级别数

traverse a "tree" dynamically given number of levels

我有一个名为 Team 的 object,它有一个 属性 Children,代表该团队 "sub teams" 下的列表

public class Team
{
    public List<Team> Children {get;set;}
} 

我目前有一些代码可以建立所有团队的单一列表,但正如您所看到的 "hard coded" 就 "levels" 而言,它下降了:

Team topTeam = GetTopteam();
List<Team> allTeams = new List<Team>();
allTeams.Add(topTeam);
allTeams.AddRange(topTeam.Children);

var childrensChildren = topTeam.Children.SelectMany(r=>r.Children);                   
allTeams.AddRange(childrensChildren);

它一直在继续。 .

我现在想使 "levels" 可配置,如下所示:

 public IEnumberable<Team> GetTeams(int numberOfLevelsDown)
 {
 }

如果我传入 1,我只会 return 顶级球队名单及其直接 children。

如果我通过 2,我将获得顶级团队,children 和 children 的 children

等等。 . .

在树中动态向下遍历层级的最优雅的方法是什么?

您可以使用递归来完成此操作。

这种方法签名是因为性能问题,它阻止生成大量中间列表。

public void GetTeams(List<Team> teams, Team team, int level)
{
    if (level == 0)
        return;

    if (team.Children == null)
        return;

    foreach (var t in team.Children)
    {
        teams.Add(t);
        GetTeams(teams, t, level - 1);
    }
}

并像这样使用它

var list = new List<Team>();
Team topTeam = GetTopteam();
GetTeams(list, topTeam, 5);
//now you have teams in list

这种东西我用过很多次

public static IEnumerable<T> EnumerateDescendants<T>(this T root, Func<T, IEnumerable<T>> children)
{
    yield return root;
    foreach (var child in children(root).SelectMany(x => x.EnumerateDescendants(children)))
    {
        yield return child;
    }
}

这样使用:

var allTeams = rootTeam.EnumerateDescendants(x => x.Children);

您应该可以像这样修改它:

public static IEnumerable<T> EnumerateDescendants<T>(this T root, Func<T, IEnumerable<T>> children, int maxLevels, int currentLevel = 0)
{
    if (currentLevel <= maxLevels)
    {
        yield return root;
        foreach (var child in children(root).SelectMany(x => x.EnumerateDescendants(children, maxLevels, currentLevel + 1)))
        {
            yield return child;
        }
    }
}

你应该可以像这样使用它:

var allTeamsUpToLevel2 = rootTeam.EnumerateDescendants(x => x.Children, 2);

我可能把 >= 搞混了,但像这样应该可以。