2010-07-06 86 views
43

我有2個IEnumerable集合。從IEnumerable刪除項目<T>

IEnumerable<MyClass> objectsToExcept 

IEnumerable<MyClass> allObjects. 

objectsToExcept可以從allObjects包含對象。

我需要從allObjects中刪除objectsToExcept中的對象。例如:

foreach (var myClass in objectsToExcept) 
{ 
allObjects.Remove(myClass); 
} 

或者

allObject.Except(objectsToExcept) 

但它不工作。方法執行後的計數表明沒有項目被移除。

回答

58

我看不出第一個版本是如何編譯的,第二個版本除非使用結果,否則不會執行任何操作。它不會刪除現有集合中的任何內容 - 事實上,甚至可能不會支持它的內存集合。它只是返回一個序列,在迭代時將返回適當的值。

如果你使用結果,例如,

IEnumerable<MyClass> others = allObjects.Except(objectsToExcept); 
foreach (MyClass x in others) 
{ 
    ... 
} 

然後如果你覆蓋GetHashCodeEquals如果你樂於使用引用相等應該罰款。你試圖刪除邏輯上相等的值,或者做同樣的引用發生在兩個序列中嗎?你有沒有重寫GetHashCodeEquals,如果是這樣,你確定這些實現工作?

基本上它應該沒問題 - 我建議你嘗試創建一個簡短但完整的程序來演示問題;我懷疑這樣做的時候,你會發現什麼是錯的。

16

刪除和刪除不修改原始的IEnumerable。他們返回一個新的。嘗試

var result = allObject.Except(objectsToexcept); 
28

上有IEnumerable<T>沒有Remove方法,因爲它並不意味着要修改。

Except方法不會修改原始集合:它返回一個新的集合,它不包含排除的項目:

var notExcluded = allObjects.Except(objectsToExcept); 

ExceptMSDN

+4

'Remove'在Linq to XML空間中作爲擴展方法存在,但不執行OP正在嘗試做的事情。奇怪的是,你可以在IEnumerable 的成員的文檔頁面上看到它,但它有一個限制'where T:XNode'。技術上'Except'也不在'IEnumerable '上,但這絕對太挑剔。 – 2010-07-06 12:18:26

+1

@Mike二,的確,我從來沒有注意到...它看起來像文檔中的一個錯誤 – 2010-07-06 13:29:48

3

雖然其他答案是正確的,但我必須補充說明Except()調用的結果可以分配回原始變量。也就是說,

allObjects = allObjects.Except(objectsToExcept); 

而且記住,Except()將產生兩個集合的差集,因此,如果有變量的副本被刪除,它們都將被刪除。

0
others.Where(contract => !objectsToExcept.Any()).ToList();