2010-06-29 44 views
5

Tengo esto y todo parece funcionar bien, pero no estoy seguro de por qué y si es válido.C# - Eliminar elementos del diccionario en while loop

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

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

Actualización: Gracias por las respuestas, he actualizado mi código para explicar por qué no hago Dictionary.Clear();

Respuesta

10

No hay nada de malo en mutar un tipo de colección en un ciclo while de esta manera. Donde se mete en problemas es cuando muta una colección durante un bloque foreach. O, de forma más general, use un IEnumerator<T> después de que la colección subyacente esté mutada.

Aunque en esta muestra sería mucho más simple que sólo llame test.Clear() :)

1

que funciona, muy bien, ya que no está interactuando sobre el diccionario, mientras que la eliminación de elementos. Cada vez que verificas la prueba. Contestar, es como si estuvieras verificando desde cero.

Dicho esto, el código anterior se podría escribir mucho más simple y efectiva:

test.Clear(); 
1

Funciona porque el conde se actualizará cada vez que se quita un objeto. Entonces digamos que el recuento es 3, prueba. Remover afectará el recuento a 2, y así sucesivamente, hasta que el conteo sea 0, entonces saldrá del ciclo

0

Todo lo que está haciendo es tomar el último elemento de la colección y eliminarlo hasta que no queden más elementos en el Diccionario.

Nada fuera de lo normal y no hay ninguna razón por la que no debería funcionar (siempre que lo que desea hacer sea vaciar la colección).

0

Entonces, solo está intentando borrar el diccionario, ¿correcto? ¿No podrías hacer lo siguiente?

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

esto parece que va a funcionar, pero parece extremadamente caro. Esto sería un problema si estuvieras iterando sobre él con un bucle foreach (no puedes editar colecciones mientras estás iterando).

Dictionary.Clear() debería hacer el truco (pero probablemente ya lo sabía).

0

A pesar de su actualización, es probable que pueda seguir utilizando clara ...

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

Su llamada a .Last() va a ser extremadamente ineficiente en un diccionario grande, y no garantiza ningún orden particular del procesamiento independientemente (el Diccionario es una colección desordenada)

8

No entiendo por qué está tratando de procesar todas las entradas de Dictonary en orden inverso, pero su código es correcto.

Podría ser un poco más rápido para obtener una lista de todas las claves y procesar las entradas por clave en lugar de contar una y otra vez ...

POR EJEMPLO:

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

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

Dictonarys son rápidos cuando se accede por su valor de clave. Last() es más lento y no es necesario contar; puede obtener una lista de todas las claves (únicas).