在对象中使用Linq的列表嵌套列表

5

我有一份电影列表

List<Movie> MovieList

我有一个选定类别的列表

List<string> SelCat

假设我想从电影列表中选择符合2个类别的电影,就像下面的SQL语句:

SELECT * FROM MovieList WHERE MovieList.Category = 'Action' AND MovieList.Category = 'Drama'

我可以用Linq接近实现:

var q = (from b in MovieList where b.Categories.Any(p=> SelCat.Contains(p)) select b);

但它像一个OR查询一样,而不是AND查询。 我想选择所有具有动作和戏剧类别的电影。

顺便说一下:Movie.Categories是字符串列表。 且Movie.Categories必须包含SelCat中的项目

如何在Linq to Objects中实现这一点?


MovieList.Category = 'Action' AND MovieList.Category = 'Drama',你是不是想说 MovieList.Category = 'Action' OR MovieList.Category = 'Drama'? - hazimdikenli
不是的,MovieList.Categories 是一个 List<string>。 - Rick Rat
你想找到所有既是动作又是戏剧类型的电影吗?那么只有戏剧类型的电影不是你想要的吗? - Matt Ellen
是的。所有同时具有动作和戏剧元素的电影,或者在SelCat字符串列表中的任何内容。 - Rick Rat
7个回答

8
var q = from m in MovieList where SelCat.All(c => m.Categories.Contains(c))

描述问题的方式与用英语描述问题时非常接近:

选择电影,其中电影类别包含SelCat中的所有类别。


1
如果您想让电影匹配所有有趣的类别(即SelCat中的所有类别都存在于movie.Categories中),可以执行以下操作:
MovieList.Where(movie => !SelCat.Except(movie.Categories).Any()); 

另一方面,如果您希望电影至少符合所选类别中的2个:

MovieList.Where(movie => SelCat.Intersect(movie.Categories).Count() >= 2); 

接近了,但我只得到了132条记录,而我应该有183条。感谢你的尝试! - Rick Rat
3
OP举的例子不好。虽然“动作”和“戏剧”让其他人难以理解,但它们本质上是SelCat中的元素。请注意,我的翻译不包括解释或其他额外内容。 - Cheng Chen
@Rick Ratayczak:如果您能描述一下为什么这不是您想要的,那将会很有帮助。 - Ani
SelCat 包含 List<string> 中的任意数量字符串。Movie.Categories 必须包含所有 SelCat 项。无论如何,谢谢。 - Rick Rat
@Rick Ratayczak:这正是我第一个查询所做的。 - Ani

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

0

先进行交集操作,然后再进行排除操作。 它很有效,很抱歉我必须用 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

很遗憾,这不是正确的答案。我不知道它会是动作片、戏剧片还是喜剧片,但是电影类别必须包含SelCat中的项目。 - Rick Rat

0

试一下这个

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

这也很接近,但只返回132条记录,而我知道有183条。谢谢! - Rick Rat

0
有点复杂:
var moviesInSelCat = MovieList.Where(m => SelCat.All(sc => m.Category.Any(c => c == sc)));

0
var result = from movie in movieList
             where selCat.All(selectedCategory => movie.Categories.Contains(selectedCategory))
             select movie;

记住.All().Any()之间的区别


1
这将选择其分类是所选分类子集的电影。 OP想要实现相反的效果。 - Jon
谢谢,但是我从那个查询中没有获取到任何记录。 - Rick Rat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接