Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda Expression to filter a list of list of items

Tags:

c#

.net

lambda

I have a a list of list of items and I was wondering if someone could help me with a lambda expression to filter this list.

Here's what my list looks like:

List<List<Item>> myList = ExtractList();

Here's what my Item class looks like:

public class Item {
    public string Name {get;set;}
    public string Action {get;set;}
}

I would like to filter this list and get only those List of List of Items where the Item Name = "ABC" and item Action = "123".

Thanks for any help

like image 692
zSynopsis Avatar asked Mar 21 '12 19:03

zSynopsis


3 Answers

I think the simple LINQ syntax is the easiest to read:

var newList =
    // gets the list of items
    from listOfItems in myList
    // extracts the list of items
    from item in listOfItems
    // filters by criteria
    where item.Name == "ABC" && item.Action == "123"
    // flattens into a IEnumerable<Item>
    select item;
like image 60
code4life Avatar answered Oct 18 '22 05:10

code4life


Simple:

myList.SelectMany(sublist => sublist)
    .Where(item => item.Name == "ABC" && item.Action == "123");

This gives you all the items inside all the lists.

If you want to select sublists that contain the item instead:

myList.Where(sublist => sublist.Any(item => item.Name == "ABC" && item.Action == "123"));

And lastly if you want to preserve the same structure but only keep the items that match the filter:

var newList = myList.Select(sublist => sublist
                       .Where(item => item.Name == "ABC" && item.Action == "123")
                       .ToList()).ToList();
like image 41
Roman Starkov Avatar answered Oct 18 '22 03:10

Roman Starkov


Here's one that gets you lists that contain at list one item matching Name = "ABC" and Action = "123".

var newList = myList.Where(l => 
             l.Exists(i => i.Name == "ABC" 
                    && i.Action == "123")).ToList();

If you need only a list of list items that match the condition, you can do:

var newList = (from l in myList 
          where l.Exists(i => i.Name == "ABC" && i.Action == "123") 
          select l.Where(i => i.Name == "ABC" && i.Action == "123").ToList()).ToList();

To flatten the list above (convert into a simple list instead of lists of lists), you'll have to do a foreach loop:

List<Item> newList2 = new List<Item>();
foreach(var list in newList)
{
    newList2.AddRange(list);
}
like image 28
Diego Avatar answered Oct 18 '22 03:10

Diego