Как объединить два словаря, но на дублирующих ключах объединить значения в C#? - PullRequest
1 голос
/ 29 апреля 2020

У меня есть два словаря, каждый из которых имеет одинаковую структуру.

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})

Как мне go сделать это?

Ответы [ 3 ]

1 голос
/ 29 апреля 2020

Вы можете сначала объединить свои словари в IEnumerable<KeyValuePair<string, List<int>>>, объединив их с Concat. Мы делаем это потому, что некоторые ключи могут отсутствовать в обоих словарях, и мы хотим, чтобы они были включены в окончательный объединенный результат.

Затем мы можем сгруппировать ключи с 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 голос
/ 29 апреля 2020

Вы можете сделать это с помощью 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);
0 голосов
/ 29 апреля 2020

GroupJoin на ключ и затем объединение или SelectMany на значениях

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...