2016-12-14 3 views
0

Ich habe Sammlung von Menü-Objekt und jedes Menü-Objekt kann mehrere Kinder-Menüs und das kann auch mehrere Kinder-Menüs und so weiter haben.Verschachtelte Objekt Filterung in C#

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

Ich möchte nur aktive Menüs filtern. Wie macht man das?

Ich versuchte mit rekursiv, aber kein Glück.

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

Bitte senden Sie Ihren Code, bis die Sie –

+0

versucht haben, ich denke, die 'IsActive' Eigenschaft mit @mark_h –

+0

Es gibt keine nicht-destruktive Weise die ursprünglichen Menüobjekte zurück, mit den gefilterten Kindern. Sie müssen neue Menüobjekte mit übereinstimmenden IDs erstellen, oder Sie müssen die Filterung der untergeordneten Elemente auf den Aufrufer verzögern oder Sie müssen die nicht aktiven Menüelemente vollständig entfernen. Wähle eins. – hvd

Antwort

0

hinzufügen Eigentum zu Ihrem Menü-Klasse und verwenden es:

public class Menu 
{ 
    //Other Memebrs 

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

du versuchen könnten;

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

Es werden nur die Menüs zurückgegeben, deren IsActive-Eigenschaft wahr ist. Wenn Sie nicht daran interessiert sind, die "IsActive" -Menüs zurückzugeben, können Sie das ändern, was diese Methode zurückgibt, indem Sie die Logik in der if (menu.IsActive) -Zeile anpassen.

Wenn Sie es testen möchten, habe ich diese Konsolenanwendung erstellt;

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 Ich muss ein einzelnes Menü zurückgeben, GetActiveMenus() ist ein IEnumerable, es kompiliert nicht, wenn ich das tue, was Sie sagen. –

+0

Das sieht gut aus, aber es erstellt eine flache Menüliste. Es sollte wie die erwähnte Baumstruktur sein. –