2014-04-14 41 views
2

有一個更好的LINQ查詢,看是否有列表包含在另一個列表要比以下任一項目:是否有更好的方法來搜索列表與另一個列表

results.Where(r => r.Categories.Intersect(submittedCategories).Count() > 0) 

其中r.categories是類別列表其結果是和類別submittedCategories IA列表中的用戶想在

回答

6

篩選我會用Enumerable.Any代替Enumerable.Count

results.Where(r => r.Categories.Intersect(submittedCategories).Any()) 

方法Count()對實現ICollection(它只是返回Count集合的屬性值)的源進行了優化。但Enumerable.Intersect結果將是IEnumerable<T>所以在這種情況下Count()會遍歷所有設置:

public static int Count<TSource>(this IEnumerable<TSource> source) 
{ 
    if (source == null)  
     throw Error.ArgumentNull("source"); 

    ICollection<TSource> is2 = source as ICollection<TSource>; 
    if (is2 != null)  
     return is2.Count; 

    ICollection is3 = source as ICollection; 
    if (is3 != null)  
     return is3.Count; 

    int num = 0; 
    using (IEnumerator<TSource> enumerator = source.GetEnumerator()) 
    { 
     while (enumerator.MoveNext()) // you will fall into this case 
      num++; 
    } 
    return num; 
} 

這意味着全路口應該從兩個集合建成以知道結果項的總數。只有價值將與零比較。

Any()將停止迭代,只是在找到第一個項目後才發現所有項目不相交。

public static bool Any<TSource>(this IEnumerable<TSource> source) 
{ 
    if (source == null)  
     throw Error.ArgumentNull("source"); 

    using (IEnumerator<TSource> enumerator = source.GetEnumerator()) 
    { 
     if (enumerator.MoveNext())   
      return true;   
    } 
    return false; 
} 

另一個好處 - Any()顯示你的意圖更好。

1

嘗試使用Any()方法。

任何接收到謂詞。它確定集合中的任何元素是否與某個條件匹配。

來源:Dotnetperls

3

您也可以直接使用Any沒有Intersect

results.Where(r => r.Categories.Any(submittedCategories.Contains)) 
+1

據值得注意的是,你是不是簡單地刪除的'Intersect'使用 - 你是*替換*它的用法'Contains'。這裏有重要的事情:任何+包含複雜性O(N * M)。 Intersect + Any需要額外的內存,但複雜度爲O(N + M) –

相關問題