如何合并两个字典但在重复键上合并C#中的值?

时间:2020-04-29 11:04:36

标签: c# dictionary merge

我有两个结构相同的字典。

Dictionary<string, List<int>> dictA
Dictionary<string, List<int>> dictB

我想以这样的方式合并两个字典:对于每个键(如果它同时存在于dictA和dictB中),我会将两个列表合并在一起,并使用它作为值,否则就将其包括在内。例如:

("wow", {0,0,0})
("key", {1,2,3}) in A

("qwerty", {4,0,4})
("key", {4,5,6}) in B

成为

("wow", {0,0,0})
("qwerty", {4,0,4})
("key", {1,2,3,4,5,6})

我将如何去做?

3 个答案:

答案 0 :(得分:1)

您可以先将字典与Concat合并,将其合并到IEnumerable<KeyValuePair<string, List<int>>>中。我们这样做是因为某些字典可能在两个字典中都不存在,并且我们希望它们包含在最终的合并结果中。

然后我们可以将密钥与ToLookup分组,然后创建最终合并的Dictionary<string, List<int>>ToDictionary,确保内部分组列表被SelectMany弄平。

var dictA = new Dictionary<string, List<int>>
{
    { "wow", new List<int>{0,0,0} },
    { "key", new List<int>{1,2,3} }
};

var dictB = new Dictionary<string, List<int>>
{
    { "querty", new List<int>{4,0,4} },
    { "key", new List<int>{4,5,6} }
};

var merged = dictA
    .Concat(dictB)
    .ToLookup(kvp => kvp.Key, kvp => kvp.Value)
    .ToDictionary(group => group.Key, group => group.SelectMany(x => x).ToList());

foreach (var kvp in merged)
{
    Console.WriteLine($"{kvp.Key} -> {"{ " + string.Join(", ", kvp.Value) + " }"}");
}

输出:

wow -> { 0, 0, 0 }
key -> { 1, 2, 3, 4, 5, 6 }
querty -> { 4, 0, 4 }

答案 1 :(得分:1)

您可以使用linq来做到这一点,但是只需几个foreach循环就可以轻松实现。

var dictA = new Dictionary<string, List<int>>
{
    { "wow", new List<int>{0,0,0} },
    { "key", new List<int>{1,2,3} }
};
var dictB = new Dictionary<string, List<int>>
{
    { "querty", new List<int>{4,0,4} },
    { "key", new List<int>{4,5,6} }
};

var merged = new Dictionary<string, List<int>>();

foreach(var kvp in dictA)
{
    merged.Add(kvp.Key, kvp.Value);

    if(dictB.TryGetValue(kvp.Key, out var inB))
    {
        kvp.Value.AddRange(inB);
        dictB.Remove(kvp.Key);
    }
}

foreach (var kvp in dictB)
    merged.Add(kvp.Key, kvp.Value);

答案 2 :(得分:-1)

在键上使用GroupJoin,然后在值上使用并集或SelectMany