2013-08-20 3 views
3

Я хочу создать свойство, которое может найти глубину вложенной древовидной структуры. Ниже статические узнают глубину/уровень путем рекурсии. Но возможно ли сделать эту функцию как свойство в одном классе вместо статического метода?Найти максимальную глубину/уровень вложенной коллекции

public static int GetDepth(MenuGroup contextMenuItems) 
{ 
    if (contextMenuItems == null || contextMenuItems.Items.Count == 0) 
     return 0; 

    var subMenu = contextMenuItems.Items.Select(b => b as MenuGroup); 
    if (!subMenu.Any()) 
     return 1; 

    var subLevel = subMenu.Cast<MenuGroup>().Select(GetDepth); 
    return !subLevel.Any() ? 1 : subLevel.Max() + 1; 
} 

Некоторые подробнее о коде: MenuGroup и MenuItem получены из MenuBase

MenuGroup имеет дочерние узлы с ObservableCollection<MenuBase> Items как элементы детского

MenuItem это уездный узел без какого-либо дочернего элемента.

+1

Вы можете сделать свойство как это: ' public int Depth {get {return GetDepth (something);} private set;} 'что-то такое, что MenuGroup. Вы можете сделать метод частным и нестатичным и использовать 'this' в этом методе. – wudzik

ответ

3

Ну вы можете легко превратить его в собственность экземпляра, да:

public int Depth 
{ 
    get 
    { 
     if (Items.Count == 0) 
      return 0; 
     var subMenu = Items.Select(b => b as MenuGroup); 
     if (!subMenu.Any()) 
      return 1; 
     var subLevel = subMenu.Cast<MenuGroup>().Select(x = > x.Depth); 
     return !subLevel.Any() ? 1 : subLevel.Max() + 1; 
    } 
} 

Это не довольно работа еще в связи с обработкой не- MenuGroup элементов, но она легко может быть исправлено, используя OfType вместо Select, а затем Cast:

public int Depth 
{ 
    get 
    { 
     // Completely empty menu (not even any straight items). 0 depth. 
     if (Items.Count == 0) 
     { 
      return 0; 
     } 
     // We've either got items (which would give us a depth of 1) or 
     // items and groups, so find the maximum depth of any subgroups, 
     // and add 1. 
     return Items.OfType<MenuGroup>() 
        .Select(x => x.Depth) 
        .DefaultIfEmpty() // 0 if we have no subgroups 
        .Max() + 1; 
    } 
} 
+1

@defaultlocale: На самом деле это не было * совершенно * ненужным. Мне потребовалось некоторое время, чтобы понять, что происходит, но я думаю, что у меня есть это сейчас. 'OfType', конечно, чище, но я согласен - см. Мой отредактированный ответ. –

0
public string GenerateMenu() 
{ 
    StringBuilder sb = new StringBuilder(); 
    sb.Append("<nav id=\"nvMenu\" class=\"main-nav\"><ul>"); 
    sb.Append(PrepareMenuUL(AppConfig._AppConfigInstance.Navigation.FirstOrDefault().NavigationClass)); 
    sb.Append("</ul></nav>"); 
    return sb.ToString(); 
} 

private string PrepareMenuUL(List<Navigation> navigation) 
{ 
    StringBuilder sb = new StringBuilder(); 

    if (Liflag == 1) 
    { 
     sb.Append("</li>"); 
     Liflag = 0; 
    } 

    foreach (var item in navigation) 
    { 
     var subMenu = item.NavigationClass.Select(b => b as Navigation); 

     if (subMenu.Any()) 
     { 
      sb.Append("<li class=\"dropdown\">"); 
      if (subMenu.Any() && item.Url == "#") 
       sb.Append(string.Format("<a href=\"{0}\">{1}<i class=\"icon-arrow\"></i></a>", BaseUrl + item.Url, item.Name)); 
      else if (subMenu.Any() && item.Url != "#" && item.Url != null) 
       sb.Append(string.Format("<a href=\"{0}\">{1}<i class=\"icon-rightarrow\"></i></a>", BaseUrl + item.Url, item.Name)); 
     } 
     else 
     { 
      sb.Append("<li>"); 
      sb.Append(string.Format("<a href=\"{0}\">{1}</a>", BaseUrl + item.Url, item.Name)); 
     } 

     if (subMenu.Any()) 
      sb.Append("<ul class=\"wd190\">"); 

     if (item.NavigationClass.Count > 0) 
     { 
      Liflag = 1; 
      sb.Append(PrepareMenuUL(item.NavigationClass)); 
     } 

     sb.Append("</li>"); 

     if (subMenu.Any()) 
      sb.Append("</ul>"); 
    } 

    return sb.ToString(); 
} 
+0

Вы можете указать рекурсию для поиска глубины списка. в приведенном выше порядке – Preetika

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