pedrodbsa
pedrodbsa

Reputation: 1431

LINQ - filter collection inside collection

Let's say I have the following classes:

class Parent
{
    bool Gender { get; set; }
    List<Child> Children { get; set; }
}


class Child
{
    bool Gender { get; set; }
    List<Child> GrandChildren { get; set; }
}


class GrandChild
{
    bool Gender { get; set; }
}

Using linq, can anyone help me filter a Parent object by returning a List<Child> where each Child has Gender == false and each Child's GrandChild has Gender == false?

I've managed to return a List<GrandChild> but I really need the hierarchy to be maintained.

Upvotes: 6

Views: 29911

Answers (4)

fejesjoco
fejesjoco

Reputation: 11903

Your question is a bit vague. Here's a solution which rebuilds the children and grandchildren lists, I wasn't sure if I needed the child.GrandChildren.All(gc => !gc.Gender) so I left it out for clarity:

parents.Select(parent => new Parent
{
  Gender = parent.Gender,
  Children = parent.Children.Where(child => !child.Gender).Select(child => new Child
    {
      Gender = false,
      GrandChildren = child.GrandChildren.Where(gc => !gc.Gender).ToList()
    }
  ).ToList()
})

Upvotes: 7

Amy B
Amy B

Reputation: 110221

  • help me filter a Parent object
  • by returning a List<Child>
  • where each Child has Gender == false
  • and each Child's GrandChild has Gender == false?

Translated literally:

List<Child> results =
(
  from c in theParent.Children
  where !c.Gender
  where c.GrandChildren.Any(gc => !gc.Gender)
  select c
).ToList()

Based on your comments, what you really want:

List<Parent> result = 
(
from p in Parents
where !p.Gender
select new Parent()
{
  Gender = p.Gender,
  Children = 
  (
    from c in p.Children
    where !c.Gender
    select new Child()
    {
      Gender = c.Gender,
      GrandChildren =
      (
        from gc in c.GrandChildren
        where !gc.Gender
        select new GrandChild()
        {
          Gender = gc.Gender
        }
      ).ToList()
    }
  ).ToList()
}).ToList();

Upvotes: 3

SLaks
SLaks

Reputation: 888223

You're looking for

.Where(p => p.Children.All(c => !c.Gender && c.GrandChildren.All(g => !g.Gender))

Upvotes: 18

decyclone
decyclone

Reputation: 30840

var filteredParents = 
    from p in parents
    where p.Children.All(child => !child.Gender &&
                         child.GrandChildren.All(grandChild => !grandChild.Gender))
    select p;

Using All method here ensures that the predicate passed as an argument to that method is true for all elements in given sequence.

Given code checks for each parent that has All children with (Gender = false and also having All grand children Gender = false).

Upvotes: 1

Related Questions