Удалить элементы из IEnumerable <T>
У меня есть 2 коллекции IEnumerable.
IEnumerable<MyClass> objectsToExcept
и
IEnumerable<MyClass> allObjects.
objectsToExcept
может содержать объекты из allObjects
.
Мне нужно удалить из allObjects
объектов в objectsToExcept
. Например:
foreach (var myClass in objectsToExcept)
{
allObjects.Remove(myClass);
}
или
allObject.Except(objectsToExcept)
Но это не сработает. Счетчик после выполнения методов указывает, что элементы не были удалены.
Ответы
Ответ 1
Я не вижу, как будет скомпилирована первая версия, а вторая версия ничего не сделает, если вы не используете результат. Он не удаляет что-либо из существующей коллекции - действительно, в ней не может быть встроенной памяти. Он просто возвращает последовательность, которая после повторения вернет соответствующие значения.
Если вы используете результат, например
IEnumerable<MyClass> others = allObjects.Except(objectsToExcept);
foreach (MyClass x in others)
{
...
}
тогда это должно быть хорошо, если вы переопределили GetHashCode
и Equals
, или если вы счастливы использовать ссылочное равенство. Вы пытаетесь удалить логически равные значения или делать одни и те же ссылки в обеих последовательностях? Вы переопределили GetHashCode
и Equals
, и если да, уверены ли вы, что эти реализации работают?
В принципе это должно быть хорошо - я предлагаю вам попробовать создать короткую, но полную программу, которая демонстрирует проблему; Я подозреваю, что при этом вы узнаете, что не так.
Ответ 2
В IEnumerable<T>
нет метода Remove
, поскольку он не предназначен для модификации.
Метод Except
не изменяет исходную коллекцию: он возвращает новую коллекцию, которая не содержит исключенных элементов:
var notExcluded = allObjects.Except(objectsToExcept);
См. Except
на MSDN.
Ответ 3
Удалить и не изменять оригинальный IEnumerable. Они возвращают новый. попробуйте
var result = allObject.Except(objectsToexcept);
Ответ 4
В то время как другие ответы верны, я должен добавить, что результат вызова Except()
можно вернуть обратно к исходной переменной. То есть
allObjects = allObjects.Except(objectsToExcept);
Также имейте в виду, что Except()
создаст заданную разницу между двумя коллекциями, поэтому, если есть дубликаты переменных, которые нужно удалить, все они будут удалены.
Ответ 5
others.Where(contract => !objectsToExcept.Any()).ToList();