Reputation: 1732
I have a list of movies
List<Movie> MovieList
and I have a list of selected categories
List<string> SelCat
And say I want to select from the movie list where it matches 2 categories, like the SQL statement below:
SELECT * FROM MovieList WHERE MovieList.Category = 'Action' AND MovieList.Category = 'Drama'
I can get kinda close with linq like so:
var q = (from b in MovieList where b.Categories.Any(p=> SelCat.Contains(p)) select b);
But it acts like an OR query, not an AND. I want it to select all movies that have a category of action and drama.
BTW: Movie.Categories is a List of string. AND Movie.Categories must contain items in the SelCat.
How do I achieve this with Linq to Objects?
Upvotes: 5
Views: 20285
Reputation: 113402
If you want the movie to match all of the interesting categories (i.e. all of the categories in SelCat
are present in movie.Categories
), you can do:
MovieList.Where(movie => !SelCat.Except(movie.Categories).Any());
On the other hand, if you want the movie to match atleast 2 of the selected categories:
MovieList.Where(movie => SelCat.Intersect(movie.Categories).Count() >= 2);
Upvotes: 1
Reputation: 437376
var q = from m in MovieList where SelCat.All(c => m.Categories.Contains(c))
Quite close to what you would say describing the problem in English:
Select movies where the movie categories contain all the categories in SelCat
.
Upvotes: 8
Reputation: 5358
just do an intersect followed by except. it works, im sorry i had to write it in vb.
Dim categories As New List(Of String)
Dim selected As New List(Of String)
categories.Add("ali")
categories.Add("ali2")
categories.Add("ali3")
categories.Add("ali4")
selected.Add("ali2")
selected.Add("ali4")
Dim common = categories.Intersect(selected)
If common.Except(selected).Count = 0 Then
'true
Else
'false
End If
Upvotes: 0
Reputation: 6019
var SelectedCategories = List<string>();//list of selected categories
from movie in MovieList
join selCat in Categories.Where(SelectedCategories.Contains(selCat.Category)
on movie.category equals selCat.category
select movie
Upvotes: 1
Reputation: 20461
try this
var matches = MovieList.Where(m => SelCat.Except(
m.Categories.Intersect(SelCat)).Count() == 0);
Upvotes: 0
Reputation: 57210
A bit convoluted:
var moviesInSelCat = MovieList.Where(m => SelCat.All(sc => m.Category.Any(c => c == sc)));
Upvotes: 0
Reputation:
var result = from movie in movieList
where selCat.All(selectedCategory => movie.Categories.Contains(selectedCategory))
select movie;
remember the difference between .All()
and .Any()
Upvotes: 0