从C#中的列表中删除对象和子对象,它们与另一个列表中的对象属性匹配

时间:2015-04-22 23:56:19

标签: c# linq

我需要一个C#LINQ查询,我根据它们是否与另一个列表中的属性匹配来删除列表中的对象。另外,这些对象可以包含相同类型的子对象,如果没有匹配,我也需要删除它们。

在我的例子中,我也想删除孩子的孩子。匹配不需要是分层的 - 只是基本匹配。这是我的课程和失败的尝试。任何帮助都会很棒!

public class GsdMegaMenu
    {
        public int Id { get; set; } 
        public int PortalId { get; set; }   
        public int TabId { get; set; }  
    }


public class MenuItem
    {
        public int Id { get; set; } 
        public int PortalId { get; set; }   
        public int TabId { get; set; }
        public List<MenuItem> Children { get; set; }

    }


List<GsdMegaMenu> megaMenuItems = GsdMegaMenu.GetAllGsdMegaMenus();
RootNode.Children.RemoveAll(x => !megaMenuItems.Any(y => y.TabId == x.TabId));

1 个答案:

答案 0 :(得分:2)

如果你还需要处理孩子的孩子,你必须明确地循环它们。 RemoveAll不是linq方法,它是List类的方法。您需要在每个子列表上调用它。

RootNode.Children.RemoveAll(x => megaMenuItems.All(y => y.TabId != x.TabId));
foreach (MenuItem node in RootNode.Children)
{
    if (node.Children != null)
    {
        node.Children.RemoveAll(x => megaMenuItems.All(y => y.TabId != x.TabId));
    }
 }

<强>更新

如果你是纯粹的LINQ解决方案,它必须是只读的,即它不能操纵现有的列表,它可以创建新的列表。我不会在你的情况下推荐它。在你的情况下,上面的循环似乎更合适。

RootNode = RootNode.Children.Where(x => megaMenuItems.Select(y => y.TabId).Contains(x.TabId))
    .Select(z => new MenuItem
    {
        Id = z.Id, PortalId = z.PortalId, TabId = z.TabId, 
        Children = z.Children == null ? null 
            : z.Children.Where(x => megaMenuItems.Select(y => y.TabId).Contains(x.TabId)).ToList()       
    })
    .ToList();

为了提高效率(在你的情况下并不重要),你也可以将其重写为:

Func<MenuItem, bool> predicate = x => megaMenuItems.Select(y => y.TabId).Contains(x.TabId);
RootNode = RootNode.Children.Where(predicate)
    .Select(z => new MenuItem
    {
        Id = z.Id, PortalId = z.PortalId, TabId = z.TabId, 
        Children = z.Children == null ? null
            : z.Children.Where(predicate).ToList()
    })
    .ToList();