linq - Remove objects, and child objects from a list in C# where they match an object property in another list -
i need c# linq query remove objects in list based on whether match property in list. in addition, objects can contain children of same type , need remove them if there not match.
in example, want remove children of children. match doesn't need hierarchical - basic match. here classes , failed attempt. awesome!
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));
if need process children of children have explicitly loop though them. removeall not linq method it's method on list
class. need call on every children 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)); } }
update
if after purely linq solution has read-only, can't manipulate existing lists, can create new ones. not recommend in case though. in case loop above seems more fitting.
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();
for efficiency (not matter in case), rewrite this:
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();