Reputation: 363
I have two dictionaries each with the same structure.
Dictionary<string, List<int>> dictA
Dictionary<string, List<int>> dictB
I want to merge the two dictionaries in such a way that for each key if it exists in both dictA and dictB I combine the the two lists together and use that as the value otherwise it just gets included. eg:
("wow", {0,0,0})
("key", {1,2,3}) in A
("qwerty", {4,0,4})
("key", {4,5,6}) in B
becomes
("wow", {0,0,0})
("qwerty", {4,0,4})
("key", {1,2,3,4,5,6})
How would I go about doing this?
Upvotes: 2
Views: 2502
Reputation: 1379
You can do it with linq but it's simple to do with just a couple foreach loops.
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);
Upvotes: 1
Reputation: 26315
You could first merge your dictionaries in a IEnumerable<KeyValuePair<string, List<int>>>
by combining them with Concat
. We do this because some keys may not exist in both dictionaries, and we want them included in the final merged result.
We can then group the keys with ToLookup
, then create a final merged Dictionary<string, List<int>>
with ToDictionary
, ensuring that the inner grouped lists are flattened with 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) + " }"}");
}
Output:
wow -> { 0, 0, 0 }
key -> { 1, 2, 3, 4, 5, 6 }
querty -> { 4, 0, 4 }
Upvotes: 1