在迭代期间从sortedlist中删除安全吗?
-
01-10-2019 - |
题
我的问题是,枚举者可以从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);
}
解决方案
这将引发异常 - 您无法在迭代时修改集合。
如果您考虑一点,您将理解原因。如果允许从集合中添加或删除,您将不再在同一集合上迭代 - 您要么有太多(添加)或不足的项目(删除)。
其他提示
正如已经说明您要做的事情是不可能的。但是,另一种解决方案是简单地维护标记为删除的项目列表,然后删除这些后词。我也会选择一个 foreach
而不是一个 while
循环,更少的代码
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);
}
}
或者,如果您只是尝试检索删除项目,请使用LINQ
var removeList = myDictionary.Where(pair => pair.Key > 1).Select(k => k.Key).ToList();
然后只需将它们从列表中删除。
// remove from the main collection
foreach (var key in removeList)
{
myDictionary.Remove(key);
}
一般而言,在迭代期间列表上的操作不支持。预期的行为是抛出例外,但是即使收藏不这样做,您也不能正确依靠此工作。
您可以首先将元素复制到另一个列表中,然后在要修改的项目列表中迭代。
否。我同意,由于有固定的索引,因此已经枚举的项目可能是可删除的。但是,问题是以下内容:
SortedList的实施不够聪明,无法确定删除不会影响枚举的进一步执行。为了保持简单和表现良好,不应该。
正如其他人已经指出的那样,它将行不通。但是,由于该集合是一个排序列表,因此您可以使用removeat方法。
此方法具有更好的内存配置文件,因为它不需要开销,而不是使用单独列表的O(n)增加来跟踪删除。与O(n^2 * log(n))相反,它也具有O(n^2)性能配置文件。 REMOVEAT方法为O(n),因为它必须执行数组副本。删除方法添加了O(log(n))操作以在内部调用removeat之前查找索引。所有这些可能都不关心您,但是如果您遇到涉及很多“ 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++;
}
}
另一个解决方案:
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--;
}
}
不隶属于 StackOverflow