2016-12-14 140 views
0

我有菜单对象的集合,每个菜单对象可以有多个子菜单,也可以有多个子菜单等等。在C中嵌套对象过滤#

MenuID 
MenuName 
IsActive 
Children 
     MenuID 
     MenuName 
     IsActive 
     Children 
       MenuID 
       MenuName 
       IsActive 
       Children 

我只想过滤活动菜单。这个怎么做?

我尝试了递归,但没有运气。

private void FilterDeletedRecord(List<Menu> menus) 
     { 
      if (menus != null && menus.Count > 0) 
      { 
       foreach (Menu item in menus) 
       { 
        if (item.Children != null && item.Children.Count > 0) 
        { 
         item.Children = item.Children.Where(x => !x.IsDeleted).ToList(); 
         if (item.Children != null && item.Children.Count > 0) 
      { 
          foreach (Menu m in item.Children) 
          { 
           if (m.Children != null && m.Children.Count > 0) 
           { 
            FilterDeletedRecord(m.Children); 
           } 
          } 
      } 
        } 
       } 
      } 
     } 
+0

请发表您的代码,直到你已经尝试 –

+0

我觉得用'IsActive'财产@mark_h –

+0

有没有非破坏性的方法,返回原始菜单对象,用过滤的孩子们。您必须创建具有匹配ID的新菜单对象,或者必须延迟向调用方过滤孩子,或者必须彻底破坏性地删除非活动菜单项。选一个。 – hvd

回答

0

添加新的物业给你的菜单类,并使用它:

public class Menu 
{ 
    //Other Memebrs 

    public IEnumerable<Menu> ActiveMenus 
    { 
     get 
     { 
      return Childeren?.Where(s => !s.IsDeleted); 
     } 
    } 
} 
0

你可以试试这个;

IEnumerable<Menu> GetActiveMenus(Menu menu) 
    { 
     if (menu.IsActive) 
     { 
      yield return menu; 
     } 
     if (menu.Children == null) 
     { 
      yield break; 
     } 
     foreach (var child in menu.Children) 
     { 
      foreach (var item in GetActiveMenus(child)) 
      { 
       yield return item; 
      } 
     } 
    } 

它仅返回其IsActive属性为true的菜单。如果您不想返回“IsActive”菜单,则可以通过调整if(menu.IsActive)行中的逻辑来更改此方法返回的内容。

如果你想测试它,我创建了这个控制台应用程序;

using System; 
using System.Collections.Generic; 

namespace ConsoleApplication26 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var menu = new Menu 
      { 
       MenuID = 0, 
       IsActive = false, 
       Children = 
        new List<Menu> 
        { 
         new Menu 
         { 
          MenuID = 2, 
          IsActive = true, 
          Children = 
           new List<Menu> 
           { 
            new Menu {MenuID = 4, IsActive = true}, 
            new Menu {MenuID = 5, IsActive = false} 
           } 
         }, 
         new Menu 
         { 
          MenuID = 3, 
          IsActive = true, 
          Children = 
           new List<Menu> 
           { 
            new Menu 
            { 
             MenuID = 12, 
             IsActive = false, 
             Children = 
              new List<Menu> 
              { 
               new Menu {MenuID = 7, IsActive = true}, 
               new Menu {MenuID = 8, IsActive = false} 
              } 
            }, 
            new Menu {MenuID = 11, IsActive = true} 
           } 
         } 
        } 


      }; 

      var activeMenus = GetActiveMenus(menu); 
      foreach (var activeMenu in activeMenus) 
      { 
       Console.WriteLine(activeMenu.MenuID); 
      } 
      Console.ReadLine(); 
     } 

     static IEnumerable<Menu> GetActiveMenus(Menu menu) 
     { 
      if (menu.IsActive) 
      { 
       yield return menu; 
      } 
      if (menu.Children == null) 
      { 
       yield break; 
      } 
      foreach (var child in menu.Children) 
      { 
       foreach (var item in GetActiveMenus(child)) 
       { 
        yield return item; 
       } 
      } 
     } 

    } 

    class Menu 
    { 
     public string MenuName { get; set; } 
     public bool IsActive { get; set; } 
     public int MenuID { get; set; } 
     public IEnumerable<Menu> Children { get; set; } 
    } 
} 
+0

@ Abion47我必须返回一个菜单,GetActiveMenus()是一个IEnumerable,如果我像你说的那样它不会编译。 –

+0

这看起来不错,但它正在创建一个平面菜单列表。它应该像上面提到的树结构一样。 –