Rick Rat
Rick Rat

Reputation: 1732

Linq to objects List in list

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

Answers (7)

Ani
Ani

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

Jon
Jon

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

Ali Tarhini
Ali Tarhini

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

hazimdikenli
hazimdikenli

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

Dean Chalk
Dean Chalk

Reputation: 20461

try this

var matches = MovieList.Where(m => SelCat.Except(
    m.Categories.Intersect(SelCat)).Count() == 0);

Upvotes: 0

digEmAll
digEmAll

Reputation: 57210

A bit convoluted:

var moviesInSelCat = MovieList.Where(m => SelCat.All(sc => m.Category.Any(c => c == sc)));

Upvotes: 0

user57508
user57508

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

Related Questions