2010-07-06 4 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) 
{ 
    ... 
} 

, то это должно быть хорошо, если вы переопределены GetHashCode и Equalsили если вы счастливы использовать равенство ссылок. Вы пытаетесь удалить логически равные значения или сделать то же самое ссылки происходят в обеих последовательностях? Вы переопределили GetHashCode и Equals, и если да, уверены ли вы, что эти реализации работают?

В принципе это должно быть хорошо - я предлагаю вам попробовать создать короткую, но полную программу, которая демонстрирует проблему; Я подозреваю, что при этом вы узнаете, что случилось.

16

Удалить и не изменять оригинальный IEnumerable. Они возвращают новый. попробуйте

var result = allObject.Except(objectsToexcept); 
28

Там нет Remove метода на IEnumerable<T>, потому что она не должна быть изменяемыми.

Метод Except не изменяет оригинальную коллекцию: она возвращает новую коллекцию, которая не содержит исключенные элементы:

var notExcluded = allObjects.Except(objectsToExcept); 

Посмотреть Except на MSDN.

+4

'Удалить' существует как метод расширения в пространстве Linq для XML, но не выполняет то, что пытается сделать OP. Как ни странно, вы видите его на странице документации для членов 'IEnumerable ', но у него есть ограничение 'where T: XNode'. Технически 'Except' не находится на' IEnumerable ', но это абсолютно слишком разборчиво. –

+1

@Mike Two, действительно, я никогда не замечал этого ... это похоже на ошибку в документации –

3

В то время как другие ответы верны, я должен добавить, что результат вызова Except() можно вернуть к исходной переменной.То есть,

allObjects = allObjects.Except(objectsToExcept); 

держать Также в виду, что Except() произведет разность множеств из двух коллекций, поэтому, если есть дубликаты переменных, которые будут удалены, все они будут удалены.

Смежные вопросы