views:

252

answers:

3

Hi, Is there a way in C# to merge two dictionaries? I have two dictionaries that may has the same keys, but I am looking for a way to merge them so, in the end there is a dictionary with one key and the values from both the dictionaries merged. I found the following code but it does not handle duplicates.

Dictionary Mydictionary<string, string[]> = new Dictionary<string, string[]>();
Mydictonary.Union(secondDictionary).ToDictionary( pair => pair.Key, pair => pair.Value);
A: 

This should do it:

Dictionary<string, string[]> dict1 = new Dictionary<string, string[]>();
Dictionary<string, string[]> dict2 = new Dictionary<string, string[]>();

Dictionary<string, List<string>> combined = new Dictionary<string, List<string>>();

foreach (var pair in dict1) combined.Add(pair.Key, new List<string>(pair.Value));
foreach (var pair in dict2)
{
    List<string> list;

    if (!combined.TryGetValue(pair.Key, out list)) combined.Add(pair.Key, list = new List<string>());

    list.AddRange(pair.Value);
}

If you really want the result as a Dictionary<string, string[]>, you can tack this on to the end:

Dictionary<string, string[]> combinedArray = new Dictionary<string, string[]>();

foreach (var pair in combined) combinedArray.Add(pair.Key, pair.Value.ToArray());
Adam Robinson
A: 

Maybe something like this:

foreach (var value in secondDictionary)
    if (myDictionary.Contains(value.Key))
        myDictionary[value.Key] = myDictionary[value.Key]
                                     .Concat(value.Value).ToArray();
    else
        myDictionary[value.Key] = value.Value;
Jeffrey L Whitledge
+1  A: 

If you want a LINQ approach, try this:

Dictionary<string, string[]> firstDic = new Dictionary<string, string[]>  
{  
    {"apple", new [] {"red"}},  
    {"orange", new [] {"orange"}}  
};

Dictionary<string, string[]> secondDic = new Dictionary<string, string[]>
{
    {"apple", new [] {"green"}},
    {"banana", new [] {"yellow"}}
};

Dictionary<string, string[]> resultDic = firstDic.Union(secondDic).GroupBy(o => o.Key).ToDictionary(o => o.Key, o => o.SelectMany(kvp => kvp.Value).ToArray());

For the sample data, you'll get a Dictionary with 3 KeyValuePairs, and the item with a Key of "apple" will have an Array with "red" and "green" for the value.

GWB
Awesome!! Thanks everyone..
+1 I love your examples. I am surprised that the default equality comparer for `KeyValuePair<TKey,TValue>` is not based on `TKey`. I didn't expect the `firstDic.Union(secondDic)` to retain dups. Interesting.
Jeffrey L Whitledge