Find-or-insert with only one lookup in c# dictionary

Viewed 4652

I'm a former C++/STL programmer trying to code a fast marching algorithm using c#/.NET technology...

I'm searching for an equivalent of STL method "map::insert" that insert a value at given key if not exists, else returns an iterator to the existing key-value pair.

The only way I found does this with two lookups : one inside TryGetValue and another one in Add method :

List<Point> list;
if (!_dictionary.TryGetValue (pcost, out list))
{
    list = new List<Point> ();
    dictionary.Add (pcost, list);
}
list.Add (new Point { X = n.x, Y = n.y });

Is there something that explains why this is not possible using .NET containers ? Or did I missed some point ?

Thanks.

6 Answers

Old question, but I may have just stumbled across an acceptable solution. I use a combination of TryGetValue, ternary operator and index assignment.

var thing = _dictionary.TryGetValue(key, out var existing) ? existing : _dictionary[key] = new Thing(); 

I have written a small example for that.

class Program
{
    private static readonly Dictionary<string, string> _translations
        = new Dictionary<string, string>() { { "en", "Hello world!" } };

    private static string AddOrGetTranslation(string locale, string defaultText)
        => _translations.TryGetValue(locale, out var existingTranslation)
            ? existingTranslation
            : _translations[locale] = defaultText;

    static void Main()
    {
        var defaultText = "#hello world#";

        Console.WriteLine(AddOrGetTranslation("en", defaultText)); // -> Hello world!

        Console.WriteLine(AddOrGetTranslation("de", defaultText)); // -> #hello world#
        Console.WriteLine(AddOrGetTranslation("de", "differentDefaultText")); // -> #hello world#

        _translations["de"] = "Hallo Welt!";
        Console.WriteLine(AddOrGetTranslation("de", defaultText)); // -> Hallo Welt!
    }
}

EDIT: ⚠️ There is an uncertainty of this solution. See comments on the solution.

Related