What's the quivalent of Java Map's "computeIfAbsent" in C# Dictionary?

Viewed 347

In Java, the HashMap has a method computeIfAbsent that, if the value is not found, compute it using the given function. However, I didn't find an equivalent thing in C#'s Dictionary.

( TryAdd is similar but I want to avoid re-computing the value if the value exists in the dictionary.)

I can manually implement it

public static V ComputeIfAbsent<K, V>(this Dictionary<K, V> dict, K key, Func<K, V> generator) {
    bool exists = dict.TryGetValue(key, out var value);
    if (exists) {
        return value;
    }
    var generated = generator(key);
    dict.Add(key, generated);
    return generated;
}

But I don't want to write something duplicate to the core library.

1 Answers

I don't think Dictionary has an equivalent. Its GetValueOrDefault doesn't work since it doesn't take a function. I think your code in an extension function is about as good as you can do for Dictionary. There is a solution if you use ConcurrentDictionary; it has GetOrAdd, which does what you want. From ConcurrentDictionary:

public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
{
 ...
}

So something like

var dict = new ConcurrentDictionary<string, int>();
dict["blue"] = 3;

var v1 = dict.GetOrAdd("blue", k => k.Length); // v1 == 3

var v2 = dict.GetOrAdd("cerulean", k => k.Length); // v2 == 8

Hope this helps somebody, since you've probably moved on by now.

Cheers.

Related