我有一个Dictionary<int, int>
,并希望根据其当前值一次更新某些元素,例如将值为10的所有元素更改为值为14或其他值。
我想象一下这对于一些LINQ / lambda来说很容易,但它看起来并不像我想象的那么简单。我目前的做法是:
List<KeyValuePair<int, int>> kvps = dictionary.Where(d => d.Value == oldValue).ToList();
foreach (KeyValuePair<int, int> kvp in kvps)
{
dictionary[KeyValuePair.Key] = newValue;
}
问题是dictionary
非常大(成千上万的元素)而且我在循环中运行这些代码数千次,所以速度非常慢。必须有更好的方法......
答案 0 :(得分:6)
这可能是错误的数据结构。您试图根据它们的值查找字典条目,这与通常的模式相反。也许你可以存储当前映射到某些值的键集。然后你可以快速移动这些集,而不是分别更新每个条目。
答案 1 :(得分:2)
我会考虑编写自己的集合类型来实现这一点,即具有相同值的键实际上共享相同的值实例,以便在一个位置更改它会更改所有键。
类似于以下内容(显然,此处省略了大量代码 - 仅用于说明目的):
public class SharedValueDictionary : IDictionary<int, int>
{
private List<MyValueObject> values;
private Dictionary<int, MyValueObject> keys;
// Now, when you add a new key/value pair, you actually
// look in the values collection to see if that value already
// exists. If it does, you add an entry to keys that points to that existing object
// otherwise you create a new MyValueObject to wrap the value and add entries to
// both collections.
}
此方案需要多个版本的Add
和Remove
才能更改具有相同值的所有键,只将一个键的一个键更改为新值,删除所有键相同的值,只从值集中删除一个键。在需要时为这些场景编码应该不难。
答案 2 :(得分:0)
您需要生成一个新词典:
d = d.ToDictionary(w => w.Key, w => w.Value == 10 ? 14 : w.Value)
答案 3 :(得分:0)
我认为每个人都必须缺少的是它非常微不足道:
List<int> keys = dictionary.Keys.Where(d => d == oldValue);
您 NOT 按值查找密钥(正如其他人提供的那样)。
相反,keys.SingleOrDefault()
现在将按照定义返回等于oldValue
的单个密钥(如果它存在于字典中)。所以整个代码应简化为
if (dictionary.ContainsKey(oldValue))
dictionary[key] = newValue;
这很快。现在我有点担心这可能确实不是OP的意图,但它是他写的东西。因此,如果现有代码能够满足他的需求,他现在将拥有相同的高性能版本:)
答案 4 :(得分:0)
编辑后,这似乎立即得到改善:
foreach (var kvp in dictionary.Where(d => d.Value == oldValue))
{
kvp.Value = newValue;
}
我很确定你可以直接更新kvp,只要密钥没有改变