Usuń elementy z IEnumerable

Mam 2 liczniejsze Kolekcje.

IEnumerable<MyClass> objectsToExcept 

I

IEnumerable<MyClass> allObjects.

objectsToExcept może zawierać obiekty z allObjects.

Muszę usunąć z allObjects obiekty w objectsToExcept. Na przykład:

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

Lub

allObject.Except(objectsToExcept)
Ale to nie działa. Licznik po wykonaniu metod wskazuje, że żadne elementy nie zostały usunięte.
Author: Henk Mollema, 2010-07-06

5 answers

Nie widzę, jak skompilowałaby się pierwsza wersja, a druga wersja nic nie zrobi, jeśli nie użyjesz wyniku. Nie usuwa niczego z istniejącej kolekcji - w rzeczy samej, może nie być nawet kolekcji w pamięci wspierającej ją. Po prostu zwraca sekwencję, która po iteracji zwróci odpowiednie wartości.

Jeśli używając wyniku, np.

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

Wtedy powinno być dobrze Jeśli przekroczyłeś GetHashCode i Equals lub Jeśli korzystasz z równości referencji. Czy próbujesz usunąć logicznie równe wartości, czy te same odniesienia występują w obu sekwencjach? Czy przesadziłeś GetHashCode i Equals, a jeśli tak, to czy na pewno te implementacje działają?

W zasadzie powinno być dobrze-proponuję spróbować stworzyć krótki, ale kompletny program, który demonstruje problem; podejrzewam, że robiąc to, dowiesz się, co jest nie tak.

 58
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-06 12:03:49

Nie ma Remove Metody na IEnumerable<T>, ponieważ nie jest przeznaczona do modyfikowania.

Metoda Except nie modyfikuje oryginalnej kolekcji: zwraca nową kolekcję, która nie zawiera wykluczonych elementów:

var notExcluded = allObjects.Except(objectsToExcept);

Patrz Except na MSDN.

 29
Author: Thomas Levesque,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-12 21:31:21

Usunąć, a poza tym nie modyfikować oryginału. Zwracają nowy. try

var result = allObject.Except(objectsToexcept);
 16
Author: Mike Two,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-06 12:04:17

Podczas gdy pozostałe odpowiedzi są poprawne, muszę dodać, że wynik wywołania {[1] } można przypisać z powrotem do pierwotnej zmiennej. Czyli

allObjects = allObjects.Except(objectsToExcept);

Należy również pamiętać, że Except() stworzy różnicę zbiorów obu kolekcji, więc jeśli istnieją duplikaty zmiennych do usunięcia, wszystkie zostaną usunięte.

 3
Author: lordcheeto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-30 23:01:34
others.Where(contract => !objectsToExcept.Any()).ToList();
 0
Author: MikroDel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-02 13:49:07