[英]Linq - get objects with a list property that does not contain values in another list
[英]check if collection of objects where each contain another collection of objects contain all values of List<string> via LINQ
我有一个对象集合,其中每个对象都包含另一个对象集合。 我需要找出最快的方法来检查它是否包含List<string>
所有值。
这是一个例子:
class Video {
List<Tag> Tags;
}
class Tag{
public Tag (string name){
Name = name;
}
string Name;
}
List<string> selectedTags = new List<string>();
selectedTags.Add("Foo");
selectedTags.Add("Moo");
selectedTags.Add("Boo");
List<Video> videos = new List<Video>();
// Case A
Video videoA = new Video();
videoA.Tags = new List<Tag>();
videoA.Tags.Add(new Tag("Foo"));
videoA.Tags.Add(new Tag("Moo"));
videos.Add(videoA);
LINQ 不应选择videoA
,因为它不包含所有标签。
// Case B
Video videoB = new Video();
videoB.Tags = new List<Tag>();
videoB.Tags.Add(new Tag("Foo"));
videoB.Tags.Add(new Tag("Moo"));
videoB.Tags.Add(new Tag("Boo"));
videos.Add(videoB);
videoB
应该选择videoB
,因为它包含所有标签。
我用foreach
循环进行了尝试,但是它太慢了,因此我正在寻找LINQ解决方案。
foreach (Video video in videos) {
if (video.Tags.Count() > 0) {
bool containAllTags = true;
foreach (string tagToFind in selectedTags) {
bool tagFound = false;
foreach (Tag tagItem in video.Tags) {
if (tagToFind == tagItem.Name)
tagFound = true;
}
if (!tagFound)
containAllTags = false;
}
if (containAllTags)
result.Add(videoItem);
}
}
生成的LINQ应该如下所示:
IEnumerable<Video> = from vid in videos
where vid.Tags.( ..I dont know.. )
select vid;
我试着用几种方法.Any
, .All
,等等。但我不能找到解决办法,我不能用.Intersect
因为一个是一个List
的字符串,另一个是一个List
对象。 请注意,在正式版中, Video
和Tag
元素具有更多属性。
使用当前代码,您在逻辑上需要:
IEnumerable<Video> result = from vid in videos
where selectedTags.All(tag =>
vid.Tags.Any(t => t.Name == tag))
select vid;
或等效地:
var result = videos.Where(vid => selectedTags.All(tag =>
vid.Tags.Any(t => t.Name == tag)));
当然,这是假定您已将Tag.Name
和Video.Tags
公开-理想情况下是作为属性而不是作为字段。
请注意,我们是如何针对selectedTags
调用All
,因为(假设我已正确阅读您的要求)重要的是,视频中必须包含所有选定的标签-选择所有视频的标签并不重要。
现在,如果您要检查很多标签并且每个视频有很多标签,那可能会比较慢。
但是,知道如何优化它实际上将取决于其他一些选择:
Video.Tags
更改为集合而不是列表? 另外,您可以将每个视频投影到其“标签列表”,然后检查所选视频集中是否有未包含的视频:
var result = videos.Where(vid => !selectedTags.Except(vid.Tags.Select(t => t.Name))
.Any());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.