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?
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
.
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
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);
var result = from movie in movieList
where selCat.All(selectedCategory => movie.Categories.Contains(selectedCategory))
select movie;
remember the difference between .All()
and .Any()
A bit convoluted:
var moviesInSelCat = MovieList.Where(m => SelCat.All(sc => m.Category.Any(c => c == sc)));
try this
var matches = MovieList.Where(m => SelCat.Except(
m.Categories.Intersect(SelCat)).Count() == 0);
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
精彩评论