Concat两个字典具有相同的密钥记录

时间:2014-01-16 08:50:46

标签: c# linq dictionary

我想合并两个词典。当我尝试这个时,我得到一个关于重复键的错误。如何合并两个具有相同键的字典?

class Program
{
    static void Main(string[] args)
    {
        Dictionary<Class1.Deneme, List<string>> dict1 = new Dictionary<Class1.Deneme, List<string>>();
        Dictionary<Class1.Deneme, List<string>> dict2 = new Dictionary<Class1.Deneme, List<string>>();
        Dictionary<Class1.Deneme, List<string>> dict3 = new Dictionary<Class1.Deneme, List<string>>();

        List<string> list1 = new List<string>() { "a", "b" };
        List<string> list2 = new List<string>() { "c", "d" };
        List<string> list3 = new List<string>() { "e", "f" };
        List<string> list4 = new List<string>() { "g", "h" };

        dict1.Add(Class1.Deneme.Buyer, list1);
        dict2.Add(Class1.Deneme.Buyer, list2);
        dict3 = dict1.Concat(dict2).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

        Console.Read();
    }
}

public class Class1
{
    public enum Deneme
    { 
        Customer=1, 
        Buyer=2,
        Supplier=3
    }
}

2 个答案:

答案 0 :(得分:5)

按键对所有KeyValuePairs进行分组。然后通过选择组键作为键并将展平值作为值将这些组转换为字典(如果不需要重复的字符串,还可以在Distinct()之前应用ToList()):

dict1.Concat(dict2)
     .GroupBy(kvp => kvp.Key) // thus no duplicated keys will be added
     .ToDictionary(g => g.Key, g => g.SelectMany(kvp => kvp.Value).ToList());

答案 1 :(得分:2)

怎么样

static IDictionary<TKey, TValue> Merge<TKey, TValue>(
    this IDictionary<TKey, TValue> left,
    IDictionary<TKey, TValue> right,
    Func<TKey, TValue, TValue, TValue> valueMerger)
{
    var result = new Dictionary<TKey, TValue>();
    foreach(var pair in left.Concat(right))
    {
        if (result.ContainsKey(pair.Key))
        {
            result[pair.Key] = valueMerger(
                                   pair.Key,
                                   pair.Value,
                                   result[pair.Key]);
            continue;
        }

        result.Add(pair.Key, pair.Value);
    }

    return result;
}

所以,你需要提供一个委托来处理密钥重复的情况。使用我建议的例子,

var dictionary1 = new Dictionary<Class1.Deneme, List<string>>();
var dictionary2 = new Dictionary<Class1.Deneme, List<string>>();

var merged = dictionary1.Merge(
                 dictionary2,
                 (key, left, right) => left.Concat(right));

或者你宁愿抛出异常?

   var merged = dictionary1.Merge(
                 dictionary2,
                 (key, left, right) => throw new ArgumentException("right", ...);