在foreach循环中编辑字典值

我正在尝试从字典中构建饼图。 在展示饼图之前,我想整理一下数据。 我将删除所有饼图片的比例不到5%,然后放入“其他”饼图片。 但是我收到一个Collection was modified; enumeration operation may not execute Collection was modified; enumeration operation may not execute在运行时Collection was modified; enumeration operation may not execute异常。

我明白为什么在迭代它们时不能添加或删除字典中的项目。 不过,我不明白为什么你不能简单地改变foreach循环中现有键的值。

任何建议重新:修复我的代码,将不胜感激。

Dictionary<string, int> colStates = new Dictionary<string,int>();
// ...
// Some code to populate colStates dictionary
// ...

int OtherCount = 0;

foreach(string key in colStates.Keys)
{

    double  Percent = colStates[key] / TotalCount;

    if (Percent < 0.05)
    {
        OtherCount += colStates[key];
        colStates[key] = 0;
    }
}

colStates.Add("Other", OtherCount);

在字典中设置一个值会更新其内部的“版本号” - 这会使迭代器和任何与键或值集合关联的迭代器失效。

我确实看到了你的观点,但同时如果值集合可能在中间迭代过程中发生变化,那么会很奇怪 - 为了简单起见,只有一个版本号。

解决此类问题的常规方法是事先复制密钥集合并遍历副本,或者迭代原始集合,但保留一组您在完成迭代后应用的更改。

例如:

首先复制密钥

List<string> keys = new List<string>(colStates.Keys);
foreach(string key in keys)
{
    double percent = colStates[key] / TotalCount;    
    if (percent < 0.05)
    {
        OtherCount += colStates[key];
        colStates[key] = 0;
    }
}

要么...

创建修改列表

List<string> keysToNuke = new List<string>();
foreach(string key in colStates.Keys)
{
    double percent = colStates[key] / TotalCount;    
    if (percent < 0.05)
    {
        OtherCount += colStates[key];
        keysToNuke.Add(key);
    }
}
foreach (string key in keysToNuke)
{
    colStates[key] = 0;
}

foreach循环中调用ToList() 。 这样我们不需要临时变量副本。 它取决于自.Net 3.5以来的Linq。

using System.Linq;

foreach(string key in colStates.Keys.ToList())
{
  double  Percent = colStates[key] / TotalCount;

    if (Percent < 0.05)
    {
        OtherCount += colStates[key];
        colStates[key] = 0;
    }
}

您正在修改此行中的集合:

colStates [key] = 0;

通过这样做,你基本上是删除并重新插入某个东西(就IEnumerable而言,无论如何。

如果你编辑你正在存储的值的成员,那可以,但是你正在编辑这个值本身,IEnumberable不喜欢这样。

我使用的解决方案是消除foreach循环,并使用for循环。 一个简单的for循环不会检查你知道不会影响集合的变化。

你可以这样做:

List<string> keys = new List<string>(colStates.Keys);
for(int i = 0; i < keys.Count; i++)
{
    string key = keys[i];
    double  Percent = colStates[key] / TotalCount;
    if (Percent < 0.05)    
    {        
        OtherCount += colStates[key];
        colStates[key] = 0;    
    }
}
链接地址: http://www.djcxy.com/p/53769.html

上一篇: Editing dictionary values in a foreach loop

下一篇: GOTO still considered harmful?