Kamil
Kamil

Reputation: 165

How to remove nested(child) items in List<> using Linq?

I have a simple list.

var menu = new List<MenuItem>
{
    new MenuItem
    {
        text = "Sign In",
        icon = "fas fa-sign-in-alt",
    },
    new MenuItem
    {
        text = "Sign Out",
        icon = "fas fa-sign-out-alt",

    },
    new MenuItem
    {
        text = "Tests",
        icon = "fas fa-sign-out-alt",

    },
    new MenuItem
    {
        text = "Data",
        icon = "far fa-border-outer",
        items = new[]
        {
            new MenuItem
            {
                text = "Asset",
                icon = "far fa-copy",
            },
            new MenuItem
            {
                text = "Tasks",
                icon = "far fa-tasks"
            },
            new MenuItem
            {
                text = "Workers",
                icon = "far fa-user-friends"
            }
        }

    }

};    

I want to remove some elements from the list. So I have an array with elements to remove:

var nameToRemove = new[] 
{ 
    "Sign In", 
    "Sign Out",
    "Workers" 
};

and now I can use RemoveAll to remove containing element in my list.

 menu.RemoveAll(x => nameToRemove.Contains(x.text));

but by using RemoveAll I can't remove nested element so my list still contain "Workers". Is there a simply way to remove nested/child element in list with LINQ? Thanks for any help!

Upvotes: 0

Views: 965

Answers (1)

Johnathan Barclay
Johnathan Barclay

Reputation: 20354

The items property is an array, and you can't remove items from an array.

What you could do, is recursively select the MenuItems that you want to keep:

static IEnumerable<MenuItem> RecursiveSelect(this IEnumerable<MenuItem> items,
    Func<MenuItem, bool> keep)
{
    foreach (var item in items)
    {
        item.items = item.items?.RecursiveSelect(keep).ToArray();
        if (keep(item)) yield return item;
    }
}

Then use like this:

menu = menu.RecursiveSelect(x => !nameToRemove.Contains(x.text)).ToList();

Be aware that this creates a new List rather than updating the existing List.

Upvotes: 2

Related Questions