Domanda Rimuovi elementi da IEnumerable


Ho 2 collezioni IEnumerable.

IEnumerable<MyClass> objectsToExcept 

e

IEnumerable<MyClass> allObjects.

objectsToExcept può contenere oggetti da allObjects.

Ho bisogno di rimuovere da allObjects oggetti in objectsToExcept. Per esempio:

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

O

allObject.Except(objectsToExcept)

Ma non funziona. Il conteggio dopo l'esecuzione dei metodi indica che nessun elemento è stato rimosso.


44
2017-07-06 12:01


origine


risposte:


Non vedo come si compilerebbe la prima versione, e la seconda versione non farà nulla a meno che non si usi il risultato. Non rimuove nulla dalla collezione esistente - anzi, potrebbe anche non esserlo essere una collezione in memoria che lo supporta. Restituisce solo una sequenza che, una volta ripetuta, restituirà i valori appropriati.

Se tu siamo utilizzando il risultato, ad es.

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

allora dovrebbe andare bene Se hai scavalcato GetHashCode e Equals  o se sei felice di usare l'uguaglianza di riferimento. Stai cercando di rimuovere i valori logicamente uguali, o fare lo stesso Riferimenti si verificano in entrambe le sequenze? Hai scavalcato GetHashCode e Equalse se sì, sei sicuro che queste implementazioni funzionino?

Fondamentalmente dovrebbe andare bene - ti suggerisco di provare a creare un programma breve ma completo che mostri il problema; Sospetto che mentre lo fai, scoprirai cosa c'è che non va.


58
2017-07-06 12:03



Non c'è Remove metodo attivo IEnumerable<T>, perché non è pensato per essere modificabile.

Il Except metodo non modifica la collezione originale: restituisce una nuova collezione che non contiene gli elementi esclusi:

var notExcluded = allObjects.Except(objectsToExcept);

Vedere Except sopra MSDN.


29
2017-07-06 12:04



Rimuovi e Tranne non modificare l'IEnumerable originale. Ne restituiscono uno nuovo. provare

var result = allObject.Except(objectsToexcept);

16
2017-07-06 12:04



Mentre le altre risposte sono corrette, devo aggiungere che il risultato del Except() la chiamata può essere nuovamente assegnata alla variabile originale. Questo è,

allObjects = allObjects.Except(objectsToExcept);

Ricorda anche questo Except() produrrà la differenza di set delle due raccolte, quindi se ci sono duplicati delle variabili da rimuovere, saranno tutte rimosse.


3
2017-09-30 23:01



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

0
2018-05-02 13:49