我正在使用下面的代码来增加或插入字典中的值。如果我正在递增的键不存在,我想将其值设置为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;
}
}
这是一种合适的方式吗?
答案 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
设置为其类型的默认值。在您的情况下,默认值int
为0
,这正是您想要的。
<强> 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上进行一些测量。
这不是你问题的答案,但为了完整起见,我测量了各种类的行为,这些类对于基于整数键递增整数很有用:简单Array
,Dictionary
(@ 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
请注意,ConcurrentDictionary.TryAddOrUpdate
比Dictionary
的{{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);