2010-06-29 2 views
5

Ho questo e tutto sembra funzionare bene ma non so perché e se è valido.C# - Rimozione di elementi dal dizionario durante il ciclo

 Dictionary<string, List<string>> test = new Dictionary<string, List<string>>(); 

     while (test.Count > 0) 
     { 
      var obj = test.Last(); 
      MyMethod(obj); 
      test.Remove(obj.Key); 
     } 

Update: Grazie per le risposte, ho aggiornato il mio codice di spiegare il motivo per cui non faccio Dictionary.Clear();

risposta

10

Non c'è niente di sbagliato con la mutazione di un tipo di raccolta in un ciclo while in questo modo. Dove ti trovi nei guai è quando muti una collezione durante un blocco foreach. O più in generale usa un IEnumerator<T> dopo che la collezione sottostante è stata modificata.

Anche se in questo esempio, sarebbe molto più semplice per chiamare solo test.Clear() :)

1

che funziona, bene, visto che non stai iterare su dizionario, mentre la rimozione di elementi. Ogni volta che controlli test.Count, è come se lo stesse verificando da zero.

Detto questo, il codice di cui sopra potrebbe scrivere molto più semplice e più efficace:

test.Clear(); 
1

Funziona perché Conte sarà aggiornato ogni volta che si rimuove un oggetto. Quindi dire count è 3, test.Remove decrimenta il conteggio a 2, e così via, finché il conteggio è 0, allora si interromperà il ciclo

0

Tutto quello che stai facendo è prendere l'ultimo elemento nella raccolta e rimuoverlo fino a quando non ci sono più elementi nel dizionario.

Niente fuori dall'ordinario e non c'è motivo per cui non dovrebbe funzionare (purché lo svuotamento della raccolta sia ciò che si vuole fare).

0

Quindi, stai solo cercando di cancellare il dizionario, corretto? Non potresti semplicemente fare quanto segue?

Dictionary<string, List<string>> test = new Dictionary<string, List<string>>(); 
     test.Clear(); 
0

Sembra che funzioni, ma sembra estremamente costoso. Questo sarebbe un problema se si stesse iterando su di esso con un ciclo foreach (non è possibile modificare le raccolte mentre si sta iterando).

Dictionary.Clear() dovrebbe fare il trucco (ma probabilmente lo sapevate già).

0

Nonostante l'aggiornamento, probabilmente si può usare ancora chiaro ...

foreach(var item in test) { 
    MyMethod(item); 
} 
test.Clear() 

La chiamata a .Last() sta per essere estremamente inefficiente su un dizionario di grandi dimensioni, e non garantisce alcun ordine particolare indipendentemente dal trattamento (il dizionario è una raccolta non ordinata)

8

Non capisco perché si sta tentando di elaborare tutte le voci Dictonary in ordine inverso - ma il codice è OK.

Potrebbe essere un po 'più veloce per ottenere un elenco di tutte le chiavi ed elaborare le voci di chiave invece di contare ancora e ancora ...

AD ESEMPIO:

var keys = test.Keys.OrderByDescending(o => o).ToList(); 

foreach (var key in keys) 
{ 
    var obj = test[key]; 
    MyMethod(obj); 
    test.Remove(key); 
} 

Dictonarys sono veloci quando sono accessibili dal loro valore chiave. Ultimo() è più lento e il conteggio non è necessario - è possibile ottenere un elenco di tutte le chiavi (univoche).