Using FindAll on a List<List<T>> type

Ken Foster picture Ken Foster · Apr 7, 2010 · Viewed 7.8k times · Source

Assuming

public class MyClass
{
   public int ID {get; set; }
   public string Name {get; set; }
}

and

List<MyClass> classList = //populate with MyClass instances of various IDs

I can do

List<MyClass> result = classList.FindAll(class => class.ID == 123);

and that will give me a list of just classes with ID = 123. Works great, looks elegant.

Now, if I had

List<List<MyClass>> listOfClassLists = //populate with Lists of MyClass instances

How do I get a filtered list where the lists themselves are filtered. I tried

List<List<MyClass>> result = listOfClassLists.FindAll
                      (list => list.FindAll(class => class.ID == 123).Count > 0);

it looks elegant, but doesn't work. It only includes Lists of classes where at least one class has an ID of 123, but it includes ALL MyClass instances in that list, not just the ones that match.

I ended up having to do

List<List<MyClass>> result = Results(listOfClassLists, 123);

private List<List<MyClass>> Results(List<List<MyClass>> myListOfLists, int id)
{
   List<List<MyClass>> results = new List<List<MyClass>>();
   foreach (List<MyClass> myClassList in myListOfLists)
   {
      List<MyClass> subList = myClassList.FindAll(myClass => myClass.ID == id);
      if (subList.Count > 0)
         results.Add(subList);
   }
   return results;
}

which gets the job done, but isn't that elegant. Just looking for better ways to do a FindAll on a List of Lists.
Ken

Answer

user1228 picture user1228 · Apr 7, 2010

listOfClasses.SelectMany(x=>x).FindAll( /* yadda */)

Sorry about that, FindAll is a method of List<T>.

This

var result = from x in listOfClasses from y in x where SomeCondition(y) select y;

or

var result = listOfClasses.SelectMany(x=>x).Where(x=>SomeCondition(x));