我在C#中有以下代码,其中vector是一个[string,double]类型的Dictionary.I想要将该字典中的所有值除以一个值," magnitude"。现在,我天真的第一个代码如下:
foreach (var key in vector.Keys)
{
vector[key] = vector[key] / magnitude;
}
这引发了一个异常,说集合已在foreach中被修改。我可以创建第二个字典来将结果值写入,但我不想这样。
有没有更简单的方法,例如通过使用对所有Dictionary值进行操作的方法,如下所示?
vector.Values().Aggreagate(), vector.Values().Average()
答案 0 :(得分:8)
最简单的方法是在迭代之前复制密钥列表:
foreach (var key in vector.Keys.ToList())
{
vector[key] = vector[key] / magnitude;
}
或者:
foreach (var entry in vector.ToList())
{
vector[entry.Key] = entry.Value / magnitude;
}
(这避免了双重查找,但当然会复制更多数据。)
遗憾的是,修改现有条目的值被视为一种阻止您继续迭代密钥的变化,这是一种耻辱。
另一种方法是将可变包装类型作为值,然后您可以使用:
foreach (var wrapper in vector.Values)
{
wrapper.Value = wrapper.Value / 10;
}
根本不会修改字典 - 只是字典引用的对象。我个人不会在大多数情况下这样做,但可能适合你。
答案 1 :(得分:4)
这是因为你在迭代时修改字典。您可以尝试迭代Keys
的副本而不是实际的集合
foreach (var key in vector.Keys.ToList())
{
vector[key] = vector[key] / magnitude;
}
答案 2 :(得分:3)
您可以通过复制它来避免更改集合。
var CopiedKeys = vector.Keys.ToList();
foreach (var key in CopiedKeys)
{
vector[key] = vector[key] / magnitude;
}
答案 3 :(得分:2)
dictionary = dictionary.ToDictionary(x => x.Key, x => x.Value / magnitude);
答案 4 :(得分:1)
另一种方法是使用增量迭代器
int magnitude = 2;
for (int index = 0; index < vector.Count; index++)
{
String key = vector.ElementAt(index).Key;
vector[key] = vector[key] / magnitude;
}
答案 5 :(得分:0)
最简单的方法之一是使用普通的迭代方式,例如:
for (int i = 0; i < vector.Keys.Count; i++)
{
string key = vector.Keys.ElementAt(i);
vector[key] /= magnitude;
}
如果您想使用Linq方法,可以使用以下代码:
vector=vector
.Select(x=> new KeyValuePair<string,double>(x.Key,x.Value/magnitude))
.ToDictionary( x=>x.Key,x=>x.Value);