I am sick of doing blocks of code like this for various bits of code I have:
if (dict.ContainsKey[key]) {
dict[key] = value;
}
else {
dict.Add(key,value);
}
and for lookups (i.e. key -> list of value)
if (lookup.ContainsKey[key]) {
lookup[key].Add(value);
}
else {
lookup.Add(new List<valuetype>);
lookup[key].Add(value);
}
Is there another collections lib or extension method I should use to do this in one line of code no matter what the key and value types are?
e.g.
dict.AddOrUpdate(key,value)
lookup.AddOrUpdate(key,value)
As Evgeny says, the indexer will already replace existing values - so if you just want to unconditionally set the value for a given key, you can do
dictionary[key] = value;
The more interesting case is the "get a value, or insert it if necessary". It's easy to do with an extension method:
public static TValue GetOrCreateValue<TKey, TValue>
(this IDictionary<TKey, TValue> dictionary,
TKey key,
TValue value)
{
return dictionary.GetOrCreateValue(key, () => value);
}
public static TValue GetOrCreateValue<TKey, TValue>
(this IDictionary<TKey, TValue> dictionary,
TKey key,
Func<TValue> valueProvider)
{
TValue ret;
if (!dictionary.TryGetValue(key, out ret))
{
ret = valueProvider();
dictionary[key] = ret;
}
return ret;
}
Note the use of a delegate to create the default value - that facilitates scenarios like the "list as value" one; you don't want to create the empty list unless you have to:
dict.GetOrCreateValue(key, () => new List<int>()).Add(item);
Also note how this only performs the lookup once if the key is already present - there's no need to do a ContainsKey
and then look up the value. It still requires two lookups when it's creating the new value though.
When updating you don't need to perform a check. Simply use:
dict[key] = value
It will replace any existing value. When retrieving the value unfortunately there is no convenient single method (like setdefault
in Python), but you could make your own extension method. Something like this:
if (!lookup.TryGetValue(key, out value))
{
value = new List<T>();
lookup.Add(key, value);
}
ConcurrentDictionary in .NET 4.0 has this nice method. You could also write an extension method for this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With