簡體   English   中英

檢查每個包含另一個對象的對象的集合是否包含List的所有值 <string> 通過LINQ

[英]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對象。 請注意,在正式版中, VideoTag元素具有更多屬性。

使用當前代碼,您在邏輯上需要:

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM