![](/img/trans.png)
[英]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.