Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Linq merge two dictionaries [duplicate]

How to make the following method more functional-linq-style?

    public static Dictionary<T, T> MergeDict<T, T>(Dictionary<T, T> a, Dictionary<T, T> b)
    {
        var e = new Dictionary<T, T>();

        a.Concat(b).ToList().ForEach(pair =>
        {
            e[pair.Key] = pair.Value;
        });

        return e;
    }
like image 258
michaelr524 Avatar asked Apr 05 '12 19:04

michaelr524


2 Answers

To continue your duplicate discarding ways, just group up and take a winning item in the group (such as the Last one).

first.Concat(second)
  .GroupBy(kvp => kvp.Key, kvp => kvp.Value)
  .ToDictionary(g => g.Key, g => g.Last());
like image 156
Amy B Avatar answered Nov 04 '22 16:11

Amy B


You could use ToDictionary directly:

public static Dictionary<T, T> MergeDict<T, T>(Dictionary<T, T> a, Dictionary<T, T> b)
{
     return a.Concat(b).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}

Be aware that this will raise an exception in the case of duplicate keys.

If you need to handle duplicate keys, you'll need to decide how you want this to be handled. For example, this will remove duplicates from "b":

public static Dictionary<T, T> MergeDict<T, T>(Dictionary<T, T> a, Dictionary<T, T> b)
{
     return a.Concat(b.Where(kvp => !a.ContainsKey(kvp.Key)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}

To get the same behavior as the original, you could go the other way (keeps KeyValuePair values from "b"):

public static Dictionary<T, T> MergeDict<T, T>(Dictionary<T, T> a, Dictionary<T, T> b)
{
     return b.Concat(a.Where(kvp => !b.ContainsKey(kvp.Key)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}
like image 23
Reed Copsey Avatar answered Nov 04 '22 18:11

Reed Copsey