遍历 "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);
我可能把 >= 搞混了,但像这样应该可以。
我有一个名为 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);
我可能把 >= 搞混了,但像这样应该可以。