5

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?

4
  • MovieList.Category = 'Action' AND MovieList.Category = 'Drama', don't you mean MovieList.Category = 'Action' OR MovieList.Category = 'Drama' Commented Nov 30, 2010 at 8:20
  • No, MovieList.Categories is a List<string> Commented Nov 30, 2010 at 8:22
  • You want to find all films that are ACTION and DRAMA? So a film that only has DRAMA in its categories is not one you want? Commented Nov 30, 2010 at 8:27
  • Yes. All films that have action AND drama. or whatever is in the SelCat list of string. Commented Nov 30, 2010 at 8:28

7 Answers 7

8
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.

Sign up to request clarification or add additional context in comments.

Comments

1
   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

Comments

1

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); 

5 Comments

Close, but I only get 132 records when I should have 183. Thanks for trying!
+1 the OP is giving a bad example. "Action" and "Drama" made others hard code, but essentially they are elements in the SelCat.
@Rick Ratayczak: If you can describe why this isn't what you want, that would be helpful.
SelCat contains any number of strings in a List<string>. Movie.Categories must contain all of the SelCat items. Thank you anyways.
@Rick Ratayczak: That's exactly what my first query does.
0
var result = from movie in movieList
             where selCat.All(selectedCategory => movie.Categories.Contains(selectedCategory))
             select movie;

remember the difference between .All() and .Any()

2 Comments

This will select movies whose categories are a subset of the selected categories. The OP wants to achieve the opposite effect.
Thank you, but I get 0 records from that query.
0

A bit convoluted:

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

Comments

0

try this

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

1 Comment

This is close also, but only returns 132 records when I know there is 183. Thank you!
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

1 Comment

Unfortunately, not the right answer. I don't know if it will be action or drama or comedy, but the Movie.Categories must contain items in the SelCat.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.