2015-06-27 2 views
1

У меня есть объект под названием Команда, которая имеет свойство Children, которая представляет список «суб команд» по этой командепересекать «дерево» динамически заданное число уровней

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

Я в настоящее время есть некоторый код, который делает это, чтобы создать единый список всех команд, но как вы можете видеть его «жестко» в терминах «уровней» она идет вниз:

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); 

и продолжает идти. ,

Теперь я хочу, чтобы «уровни» настраивается так что-то вроде этого:

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

Если я прохожу в 1, я только возвращает список из topteam и его непосредственных детей.

Если я прохожу через 2, я получаю команду топ, дети и дети детей

и так далее. , ,

Что является самым элегантным способом динамического пересечения уровней в дереве?

+1

Почему не рекурсия с декрементом 'numberOfLevelsDown' на каждом уровне? – Dmitry

ответ

1

Вы можете использовать рекурсию для этого.

Этот вид сигнатуры метода вызван проблемами производительности и предотвращает создание множества промежуточных списков.

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 
0

я использовал этот вид вещь много раз.

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); 

Возможно, у меня есть> = перепутаны но что-то вроде этого должно работать.

Смежные вопросы