增加字典中的数值

我正在使用下面的代码来增加或插入一个字典中的值。 如果我正在递增的键不存在,我想将其值设置为1。

public void IncrementCount(Dictionary<int, int> someDictionary, int id) { int currentCount; if (someDictionary.TryGetValue(id, out currentCount)) { someDictionary[id] = currentCount + 1; } else { someDictionary[id] = 1; } } 

这是一个适当的方式吗?

事实certificate,使用具有方便的upsert方法的ConcurrentDictionary是有意义的:AddOrUpdate。

所以,我只是用了:

 someDictionary.AddOrUpdate(id, 1, (id, count) => count + 1); 

你的代码很好。 但是这里有一种方法可以简化,不需要在代码中分支:

 int currentCount; // currentCount will be zero if the key id doesn't exist.. someDictionary.TryGetValue(id, out currentCount); someDictionary[id] = currentCount + 1; 

这依赖于TryGetValue方法将value设置为其types的默认值(如果该键不存在)的事实。 在你的情况下, int的默认值是0 ,这正是你想要的。

这是一个很好的扩展方法:

  public static void Increment<T>(this Dictionary<T, int> dictionary, T key) { int count; dictionary.TryGetValue(key, out count); dictionary[key] = count + 1; } 

用法:

 var dictionary = new Dictionary<string, int>(); dictionary.Increment("hello"); dictionary.Increment("hello"); dictionary.Increment("world"); Assert.AreEqual(2, dictionary["hello"]); Assert.AreEqual(1, dictionary["world"]); 

它是可读的,意图是清楚的。 我认为这很好。 不需要发明一些更聪明或更短的代码; 如果它不保持意图就像你的初始版本一样清晰:-)

这就是说,这是一个稍微缩短的版本:

 public void IncrementCount(Dictionary<int, int> someDictionary, int id) { if (!someDictionary.ContainsKey(id)) someDictionary[id] = 0; someDictionary[id]++; } 

如果您可以同时访问字典,请记住同步对其的访问。

只是一些测量整数键的.NET 4。

这不是一个你的问题的答案,但为了完整起见,我测量了各种类的行为,基于整数键递增整数有用:简单的ArrayDictionary (@ Ani的方法), Dictionary (简单的方法), SortedDictionary (@ Ani的方法)和ConcurrentDictionary.TryAddOrUpdate

下面是结果,调整了2.5纳秒,用类来包装而不是直接使用:

 Array 2.5 ns/inc Dictionary (@Ani) 27.5 ns/inc Dictionary (Simple) 37.4 ns/inc SortedDictionary 192.5 ns/inc ConcurrentDictionary 79.7 ns/inc 

这就是代码 。

请注意, ConcurrentDictionary.TryAddOrUpdateDictionaryTryGetValue + indexer的setter慢三倍。 而后者比Array慢十倍。

所以我会使用一个数组,如果我知道键的范围很小,否则组合的方法。

下面是一个方便的unit testing,您可以使用ConcurrentDictionary以及如何保持值线程安全:

  ConcurrentDictionary<string, int> TestDict = new ConcurrentDictionary<string,int>(); [TestMethod] public void WorkingWithConcurrentDictionary() { //If Test doesn't exist in the dictionary it will be added with a value of 0 TestDict.AddOrUpdate("Test", 0, (OldKey, OldValue) => OldValue+1); //This will increment the test key value by 1 TestDict.AddOrUpdate("Test", 0, (OldKey, OldValue) => OldValue+1); Assert.IsTrue(TestDict["Test"] == 1); //This will increment it again TestDict.AddOrUpdate("Test", 0, (OldKey, OldValue) => OldValue+1); Assert.IsTrue(TestDict["Test"] == 2); //This is a handy way of getting a value from the dictionary in a thread safe manner //It would set the Test key to 0 if it didn't already exist in the dictionary Assert.IsTrue(TestDict.GetOrAdd("Test", 0) == 2); //This will decriment the Test Key by one TestDict.AddOrUpdate("Test", 0, (OldKey, OldValue) => OldValue-1); Assert.IsTrue(TestDict["Test"] == 1); }