2016-12-14 15 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

あなたはフィルタの子供たちと、元のメニューオブジェクトを返すために何の非破壊方法はありません@mark_h –

+0

を試してみましたまであなたのコードを投稿してください。一致するIDを持つ新しいメニューオブジェクトを作成するか、呼び出し元に子のフィルタリングを遅延させるか、非アクティブなメニュー項目を完全に完全に削除する必要があります。一つを選ぶ。 –

+0

'IsActive'プロパティを使用して、私は思います – hvd

答えて

0

あなたのMenuクラスに新しいプロパティを追加し、それを使用する:

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

これは大丈夫ですが、フラットなメニューリストを作成しています。それは前述の木構造のようにすべきである。 –

関連する問題