我有一个对象集合,其中每个对象都包含另一个对象集合。我需要找出最快的方法来检查它是否包含的所有值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);
videoA
LINQ不应该选择它,因为它不包含所有标签。
// 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
应该由LINQ选择,因为它包含所有标签。
我尝试使用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
公开的-理想情况下是作为属性而不是作为字段。
请注意我们如何All
反对selectedTags
,因为(假设我已正确阅读您的要求)在视频中出现所有选定的标签很重要-选择所有视频的标签并不重要。
现在,如果您要检查很多标签并且每个视频有很多标签,那可能会比较慢。
但是,知道如何对其进行优化实际上取决于其他一些选择:
Video.Tags
为集合而不是列表吗?另外,您可以将每个视频投影到其“标签列表”,然后检查所选视频集中是否有不包含的视频:
var result = videos.Where(vid => !selectedTags.Except(vid.Tags.Select(t => t.Name))
.Any());
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句