2015-11-03 50 views
2

我有一個List<Organisation>組織。Linq通過比較兩個int類型的列表來選擇對象

每個Organisation有一個屬性List<int> Categories

我也有一個單獨的List<int> DisplayCategories

我想創建一個新的名爲List<Organisation>DisplayOrganisations

DisplayOrganisations將包含Organisation的誰的Categories出現在我的List<int> DisplayCategories

如何使用linq或lambda來實現這個功能?

以下是不正確的:

DisplayOrganisations = (from o in Organisations 
         where o.Categories.Intersect(DisplayCategories.CategoryIds) 
         select o).ToList(); 

我得到一個錯誤:

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'bool'

我認爲,這是因爲我選擇機構是誰的分類的子列表需要被比作一個單獨列表DisplayCategories。

任何想法?

+0

請不要使用secon d的方法在我的答案中。使用第一個。由於其經過驗證的Intersect更適合大型收藏。再次看到答案。 –

+0

@ M.kazemAkhgary謝謝你,我已經修改我的代碼來使用相交,就像你的更新, – fourbeatcoder

回答

3

當然相交不會給布爾值。你可能要檢查是否有任何元素存在於它使用Any

DisplayOrganisations = Organisations 
         .Where(o => o.Categories.Intersect(DisplayCategories.CategoryIds) 
               .Any()).ToList(); 

或更好的方法。 DisplayOrganisations = Organisations.Where(o => o.Categories .Any(xDisplayCategories.CategoryIds.Contains))。ToList();

正如你可以相交使用HashSet比第二種方法更快,因爲擁有的Hashset用於添加並刪除項目的O(1)時間複雜度的圖片中看到。所以一般Intersect是O(n+m)。但使用AnyContains的第二種方法的時間複雜度爲O(n^2),可能會變得更慢。感謝Dmitry Dovgopoly

enter image description here

+0

我猜測相交需要比線性搜索更多的時間。即時通訊不知道什麼是時間複雜性,但我很欣賞,如果你分享你的知識,所以我會修復我的答案,也學習一些東西;)@DmitryDovgopoly –

+1

其實第二種方法更糟。相交使用'hashset'並且很快。 「任何」都適用於所有元素,複雜度爲n * n。您可以通過從xDisplayCategories.CategoryIds'創建一個哈希集來優化它。 –

+0

感謝您的信息!非常感激。我不知道相交使用哈希集。所以我認爲這可能是找出兩個列表至少包含一個相同項目的最快方法。 (忽略微觀優化)@DmitryDovgopoly –

2

如果您只需要那些所有元素都在CategoryIds列表,你可以使用Except()Any()方法混合組織:

var DisplayOrganisations = Organisations.Where(o => 
         !o.Categories.Except(DisplayCategories.CategoryIds).Any()).ToList(); 

如果你只是想確認至少有您可以使用的ID列表中的一個ID .Any方法:

var DisplayOrganisations = Organisations.Where(o => o.Categories 
             .Any(DisplayCategories.CategoryIds.Contains)).ToList();