Search code examples
c#dictionarymerge

Merging dictionaries in C#


What's the best way to merge 2 or more dictionaries (Dictionary<TKey, TValue>) in C#? (3.0 features like LINQ are fine).

I'm thinking of a method signature along the lines of:

public static Dictionary<TKey,TValue>
                 Merge<TKey,TValue>(Dictionary<TKey,TValue>[] dictionaries);

or

public static Dictionary<TKey,TValue>
                 Merge<TKey,TValue>(IEnumerable<Dictionary<TKey,TValue>> dictionaries);

Regarding the handling of duplicate keys: In case of collision, it doesn't matter which value is saved to the dictionary as long as it's consistent.


Solution

  • This partly depends on what you want to happen if you run into duplicates. For instance, you could do:

    var result = dictionaries.SelectMany(dict => dict)
                             .ToDictionary(pair => pair.Key, pair => pair.Value);
    

    Or, more succintly, in .NET 8:

    var result = dictionaries.SelectMany(dict => dict)
                             .ToDictionary();
    

    That will throw an exception if you get any duplicate keys.

    EDIT: If you use ToLookup then you'll get a lookup which can have multiple values per key. You could then convert that to a dictionary:

    var result = dictionaries.SelectMany(dict => dict)
                             .ToLookup(pair => pair.Key, pair => pair.Value)
                             .ToDictionary(group => group.Key, group => group.First());
    

    It's a bit ugly - and inefficient - but it's the quickest way to do it in terms of code. (I haven't tested it, admittedly.)

    You could write your own ToDictionary2 extension method of course (with a better name, but I don't have time to think of one now) - it's not terribly hard to do, just overwriting (or ignoring) duplicate keys. The important bit (to my mind) is using SelectMany, and realising that a dictionary supports iteration over its key/value pairs.