Ist es sicher, von SortedList während der Iteration löschen
-
01-10-2019 - |
Frage
Meine Frage ist, ist es sicher für enumerator Artikel von SortedList zu entfernen?
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);
}
Lösung
Das wird eine Ausnahme werfen -. Sie können nicht eine Sammlung ändern, während über sie iterieren
Wenn Sie es ein wenig nachdenken, werden Sie verstehen, warum. Wenn das Hinzufügen oder aus der Sammlung erlaubt wurde entfernt, würden Sie nicht mehr Iterieren über die gleiche Sammlung sein -. Sie entweder zu viele (Hinzufügen) oder nicht genügend Elemente (Entfernen)
Andere Tipps
Wie bereits erklärt, was Sie suchen zu tun, ist nicht möglich. Allerdings wäre eine alternative Lösung einfach sein, um eine Liste der Elemente zum Löschen markiert zu halten und diese dann anschliessend entfernen. Ich würde auch entscheiden sich für eine foreach
statt einer while
Schleife, weniger Code z.
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);
}
}
Oder wenn Sie versuchen einfach, Elemente zum Löschen, die Verwendung von LINQ
abrufenvar removeList = myDictionary.Where(pair => pair.Key > 1).Select(k => k.Key).ToList();
Dann einfach entfernen Sie sie aus der Liste aus.
// remove from the main collection
foreach (var key in removeList)
{
myDictionary.Remove(key);
}
Operationen auf der Liste während der Iterationen werden im Allgemeinen nicht unterstützt. Das erwartete Verhalten ist eine Ausnahme zu werfen, aber auch wenn eine Sammlung, dies zu tun nicht verlassen müssen Sie nicht auf diese richtig funktioniert.
Sie können kopieren Sie zuerst die Elemente in einer anderen Liste und dann über Iterierte diese neue Liste der Elemente geändert werden.
Nein. Ein InvalidOperationExcpetion ausgelöst. Ich bin damit einverstanden, dass bereits aufgezählten Elemente löschbar sein könnten, da es ein fester Index. Doch das Problem ist folgendes:
Die Umsetzung der SortedList ist nicht klug genug, um herauszufinden, dass die Entfernung beeinflussen haben keinen Einfluss auf die weitere Ausführung des abzählbar. Und es einfach zu halten und gut abschneiden, sollte es nicht.
Wie andere haben bereits darauf hingewiesen, es wird nicht funktionieren. Da jedoch die Sammlung ein SortedList ist, können Sie die RemoveAt-Methode verwenden.
Dieses Verfahren hat einen etwas besseren Speicher Profil, da es keinen Overhead erfordert, im Gegensatz zu einem O (n) erhöhen, um eine separate Liste unter Verwendung Spur Umzug zu halten. Es wäre auch eine O (n ^ 2) Leistungsprofil im Gegensatz zu O (n ^ 2 * log (n)). Die RemoveAt Methode ist O (n), da es eine Reihe Kopie durchführen müssen. Die Remove-Methode fügt eine O (log (n)) Betrieb vor, den Index zu finden RemoveAt intern telefonieren. wahrscheinlich keine Bedeutung für Sie von all dem ist, aber es ist nützlich, Know falls Sie in Situationen führen eine Menge ‚n‘ beteiligt sind.
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++;
}
}
Eine andere Lösung:
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--;
}
}