Home > Enterprise >  Linq how to filter an object list based on overlap of nested list property and external list
Linq how to filter an object list based on overlap of nested list property and external list

Time:03-24

I have the object classes below. How can setup a linq query to filter the myItems list to only return items that have ItemGroups with a CategoryId that is in the categories list? So in my sample data below, I want my linq query to only return the item with ItemId = 1 since it is the only item that has an itemgroup with a CategoryId that is in the categories list.

I have tried the following, but that does not seem to work:

myItems.Where(i => categories.Contains(i.ItemGroups.Select(g => g.CategoryId)))
public ItemGroup{
    int ItemGroupId
    int CategoryId
}

public class Item(
    int ItemId;
    List<ItemGroup> ItemGroups
)

List<int> categories {2,5,7}
List<Item> myItems = [
    {
        ItemId = 1,
        ItemGroups = [
            {
                ItemGroupId = 1,
                CategoryId = 1
            },
            {
                ItemGroupId = 2,
                CategoryId = 2
            },
        ]
    },
    {
        ItemId = 2,
        ItemGroups = [
            {
                ItemGroupId = 3,
                CategoryId = 3
            },
            {
                ItemGroupId = 4,
                CategoryId = 4
            },
        ]
    }
]

CodePudding user response:

You could try using Any on ItemGroup within the Where predicate

myItems.Where(i => i.ItemGroups.Any(g => categories.Contains(g.CategoryId)));

CodePudding user response:

Here is an approach where Linq operations are nested one level, rather than two.

For each Item, .IntersectBy() is used to determine its collection of ItemGroups whose CategoryId is present in categories. If any such ItemGroup is present, the Item will be included.

IEnumerable<Item> filteredItems = myItems
    .Where(i => i.ItemGroups
        .IntersectBy(categories, gr => gr.CategoryId)
        .Any());

Example fiddle here.

  • Related