我正试图从字典中建立一个饼图。在显示饼图之前,我想整理一下数据。我去掉了所有小于5%的派片,把它们放到“其他”派片里。然而,我得到一个集合被修改;枚举操作在运行时不能执行异常。
我理解为什么在遍历字典时不能从字典中添加或删除项。但是,我不明白为什么不能简单地在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;
}
如何只是对你的字典做一些linq查询,然后将你的图绑定到这些结果?
var under = colStates.Where(c => (decimal)c.Value / (decimal)totalCount < .05M);
var over = colStates.Where(c => (decimal)c.Value / (decimal)totalCount >= .05M);
var newColStates = over.Union(new Dictionary<string, int>() { { "Other", under.Sum(c => c.Value) } });
foreach (var item in newColStates)
{
Console.WriteLine("{0}:{1}", item.Key, item.Value);
}