Pregunta

Mi pregunta es ¿es seguro para el empadronador a Quitar elemento de SortedList?

SortedList<decimal, string> myDictionary;
// omitted code

IEnumerator<decimal, string> enum = myDictionary.GetEnumerator();

while(enum.MoveNext)
{
  // is it ok to remove here?
  myDictionary.Remove(enum.Current.Key);
}
¿Fue útil?

Solución

Esto producirá una excepción -. No puede modificar una colección al iterar sobre ella

Si se piensa en ello un poco, se entiende por qué. Si la adición o eliminación de la colección estaba permitido, ya no debería estar interactuando sobre la misma colección -. Usted o tiene demasiados (adición) o no suficientes elementos (eliminación)

Otros consejos

Como ya se ha dicho lo que está buscando hacer no es posible. Sin embargo, una solución alternativa sería mantener simplemente una lista de elementos marcados para su eliminación y luego eliminar estos epílogos. Lo haría también optan por un foreach en lugar de un bucle while, por ejemplo menos código.

var removeList = new List<decimal>();
foreach (var item in myDictionary)
{
    // have a condition which indicates which items are to be removed
    if (item.Key > 1)
    {
        removeList.Add(item.Key);
    }
}

O si simplemente está tratando de recuperar los elementos para su eliminación, el uso de LINQ

var removeList = myDictionary.Where(pair => pair.Key > 1).Select(k => k.Key).ToList();

A continuación, sólo eliminarlos de la lista.

// remove from the main collection
foreach (var key in removeList)
{
    myDictionary.Remove(key);
}

Operaciones en la lista durante iteraciones no se admiten en general. El comportamiento esperado es lanzar una excepción, pero incluso si falla una colección de hacer esto que no debe confiar en esta trabajando correctamente.

En primer lugar, puede copiar los elementos en otra lista y luego iterar sobre esta nueva lista de elementos que desea modificar.

No. Un InvalidOperationExcpetion es lanzada. Estoy de acuerdo en que los elementos ya enumerados podrían ser suprimible ya que hay un índice fijo. Sin embargo, la cuestión es la siguiente:

La implementación de SortedList no es lo suficientemente inteligente como para darse cuenta de que la eliminación se no tienen ningún efecto sobre la ulterior ejecución del enumerable. Y que sea sencillo y un buen rendimiento, no debería.

Como otros ya han señalado que no va a funcionar. Sin embargo, puesto que la colección es un SortedList puede utilizar el método RemoveAt.

Este método tiene un poco mejor perfil de memoria ya que requiere ninguna sobrecarga en contraposición a un aumento O (n) utilizando una lista separada para realizar un seguimiento de las extracciones. También tendría un O (n ^ 2) perfil de rendimiento en lugar de O (n ^ 2 * log (n)). El método RemoveAt es O (n), ya que debe realizar una copia de matriz. El método Remove añade una operación O (log (n)) para encontrar el índice antes de llamar internamente RemoveAt. Todo esto es, probablemente, de ninguna preocupación para usted, pero es conocimiento útil en caso de que tenga las situaciones que implican una gran cantidad de 'n'.

var myDictionary = new SortedList<decimal, string>();

// omitted code

int i = 0;
while (myDictionary.Count > 0 && i < myDictionary.Count)
{
  if (/* predicate to use for removal */)
  {
    myDictionary.RemoveAt(i);
  }
  else
  {
    i++;
  }
}

Una otra solución:

            int counter= MyDictionary.Count;
            if (counter == 0)
                return;

            for (int i = 0;  i < counter;i++)
            {
                KeyValuePair<MyIdentifier, MyValue> key = (KeyValuePair<MyIdentifier, MyValue>)MyDictionary.ToArray()[i];
                MyIdentifier identifier = null;

                if (key.Key != null)
                    identifier = key.Key as MyIdentifier;

                if (identifier != null)
                    if (MyCondition)
                    {
                        MyDictionary.Remove(identifier);
                        counter--;
                    }
            }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top