0

I have collection of menu object and each menu object can have multiple child menus and that can also have multiple child menus and so on.

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

I want to filter only active menus. How to do this?

I Tried with recursive but no luck.

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);
                                }
                            }
            }
                    }
                }
            }
        }
  • Please post your code till which you have tried – Sethu Bala Dec 14 '16 at 11:25
  • I think using the `IsActive` property @mark_h – Jack Thorley Dec 14 '16 at 11:26
  • There's no non-destructive way to return the original menu objects, with the children filtered. You have to create new menu objects with matching IDs, or you have to delay the filtering of children to the caller, or you have to destructively remove the non-active menu items completely. Pick one. –  Dec 14 '16 at 11:28
  • So do you want to get a collection of only active menus, or do you want to fully remove the non-active menus? – Abion47 Dec 14 '16 at 11:50

2 Answers2

0

Add new Property to your Menu Class and use it:

public class Menu
{
    //Other Memebrs

    public IEnumerable<Menu> ActiveMenus
    {
        get
        {
            return Childeren?.Where(s => !s.IsDeleted);
        }
    }
}
Mazaher Bazari
  • 421
  • 5
  • 12
0

You could try this;

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

It returns only the menus whose IsActive property is true. If you are not interested in returning the "IsActive" menus you can change what this method returns by adjusting the logic in the if(menu.IsActive) line.

If you want to test it I created this console application;

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; }
    }
}
mark_h
  • 5,233
  • 4
  • 36
  • 52