增加字典中的数值

时间:2011-08-20 15:30:49

标签: c# dictionary

我正在使用下面的代码来增加或插入字典中的值。如果我正在递增的键不存在,我想将其值设置为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;
     }
 }

这是一种合适的方式吗?

7 个答案:

答案 0 :(得分:75)

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

所以,我刚才用过:

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

答案 1 :(得分:54)

你的代码很好。但这是一种简化方式,不需要在代码中进行分支:

int currentCount;

// currentCount will be zero if the key id doesn't exist..
someDictionary.TryGetValue(id, out currentCount); 

someDictionary[id] = currentCount + 1;

这取决于如果密钥不存在,TryGetValue方法将value设置为其类型的默认值。在您的情况下,默认值int0,这正是您想要的。


<强> UPD 即可。从C#7.0开始,可以使用out variables缩短此代码段:

// declare variable right where it's passed
someDictionary.TryGetValue(id, out var currentCount); 
someDictionary[id] = currentCount + 1;

答案 2 :(得分:14)

它是可读的,意图很明确。我觉得这很好。无需发明更智能或更短的代码;如果它没有像你的初始版本那样保持意图:-)

话虽如此,这是一个稍短的版本:

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

    someDictionary[id]++;
}

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

答案 3 :(得分:13)

这是一个不错的扩展方法:

    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"]);

答案 4 :(得分:5)

仅针对整数键在.NET 4上进行一些测量。

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

以下是结果,调整为2.5 ns,用于包装类而不是直接使用:

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

that's the code

请注意,ConcurrentDictionary.TryAddOrUpdateDictionary的{​​{1}} +索引器设置器慢三倍。而后者比Array慢十倍。

因此,如果我知道键的范围很小,那么我会使用数组,否则就会使用组合方法。

答案 5 :(得分:1)

这是一个方便的单元测试,供您使用有关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);
     }

答案 6 :(得分:0)

如果您正在寻找简化版本:

someDictionary.Add(id, someDictionary.GetValueOrDefault(id, 0) + 1);