2012-04-16 13 views
7

Quale è il modo più semplice per rimuovere elementi che corrispondono ad alcune condizioni da un elenco e quindi ottenere quegli elementi.LINQ: Rimuovi tutto e ottieni elementi rimossi

posso pensare in qualche modo, non so che è il migliore:

var subList = list.Where(x => x.Condition); 
list.RemoveAll(x => x.Condition); 

o

var subList = list.Where(x => x.Condition); 
list.RemoveAll(x => subList.Contains(x)); 

C'è qualcosa di questo uno dei modi migliori? Se lo è, quale? Se non lo è, come dovrei farlo?

risposta

4

Vorrei andare con la prima opzione per scopi di leggibilità, con la nota che si dovrebbe concretizzarsi il primo elenco, o ti perdere i elementi molto si sta cercando di selezionare nella riga successiva:

var sublist = list.Where(x => x.Condition).ToArray(); 
list.RemoveAll(x => x.Condition); 

Il secondo esempio è O (n^2) senza motivo e l'ultimo è perfettamente a posto, ma meno leggibile.

Modifica: ora che ho riletto il tuo ultimo esempio, nota che come è scritto in questo momento eliminerà ogni altro elemento. Manca il controllo delle condizioni e la linea di rimozione dovrebbe essere in realtà list.RemoveAt(i--); perché l'elemento i+1 diventa l'elemento i th dopo la rimozione e quando si incrementa i si sta saltando su di esso.

+0

In realtà è O (n^3), ma sto assumendo la mancanza di materializzazione appena scivolato la vostra mente;) – Blindy

+0

Gli articoli (come ho scritto) sarebbero stati rimossi da subList con la seconda istruzione? : O – Diego

+0

Non si rimuove mai da 'sottolista', né si intende farlo se l'ho letto correttamente. – Blindy

2

Mi piace utilizzare un approccio di programmazione funzionale (solo apportare nuove cose, non modificare le cose esistenti). Un vantaggio di ToLookup consiste nel fatto che è possibile gestire più di una suddivisione a due vie degli articoli.

ILookup<bool, Customer> lookup = list.ToLookup(x => x.Condition); 
List<Customer> sublist = lookup[true].ToList(); 
list = lookup[false].ToList(); 

O se è necessario modificare l'istanza originale ...

list.Clear(); 
list.AddRange(lookup[false]); 
+0

Penso che sia molto complesso (e quasi senza conoscenza penso che non sia davvero una performance). Questo ha qualche vantaggio? – Diego

+0

La condizione viene valutata esattamente una volta per articolo.L'istanza dell'elenco non viene modificata, il che può essere un grande vantaggio se quell'istanza dell'elenco è condivisa tra i thread. –

Problemi correlati