Select items from a list in which children contain items from another list using LINQ

I have the following classes:

Product:

public class Product { public string Name { get; set; } public List<Category> Categories { get; set; } } 

And Category:

 public class Category { public string Id { get; set; } public string Name { get; set; } } 

And I have the following method:

 public List<Product> FilterProducts(List<Category> categories) { // filtering code here } 

Question. How to filter my products using the List<Categories> as parameter?

EDIT: I forgot to mention that if I have 2 categories, I should only see products with category AND categories2. What I have done so far has returned only products with category 1 or category2. Although IEquatable inheritance uses Intersect seems interesting, I am comparing with Id at the moment.

+4
source share
1 answer

If you want to return all products with all the categories provided in Categories , which means that he selects a product in which he has category1 and category2.

Then you need to use All with the Contains combination:

 public List<Product> FilterProducts(List<Category> categories) { return products.Where(p => categories.All(c => p.Categories.Contains(c)) .ToList(); } 

If you want to return the entire product in which it has the smallest number of cetegory from the categories provided, this means that it selects the product in which it has category1 or category2.

Then you need to use Any

 public List<Product> FilterProducts(List<Category> categories) { return products.Where(p => categories.Any(c => p.Categories.Contains(c) .ToList(); } 

Please, not that if your Categories objects do not match the instances that you have in the Product Categories property or in your Category , you do not override the Equals method to use Id you can compare Id instead of the category objects themselves.

So something like:

Solution with all

 public List<Product> FilterProducts(List<Category> categories) { return products.Where(p => categories .All(c => p.Categories.Any(cat => cat.Id == c.Id)).ToList() } 

Solution with any

 public List<Product> FilterProducts(List<Category> categories) { return products.Where(p => categories .Any(cat => p.Categories.Any(pcat => pcat.Id == cat.Id)).ToList(); } 
+12
source

Source: https://habr.com/ru/post/1490054/