I am creating a Project-2-Categories dictionary from supplied Project-2-Groups and Group-2-Categories dictionaries.
In my code example I expected the following result:
{
"P1": [ "1", "11", "111" ],
"P2": [ "1", "11", "111", "2", "22", "222" ],
}
However, the actual result is:
{
"P1": [ "1", "11", "111", "2", "22", "222" ],
"P2": [ "1", "11", "111", "2", "22", "222" ],
}
I would appreciate any help clearing up what I am misunderstanding here.
Link to fiddle
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
var proj2categories = new Dictionary<string, List<string>>();
var proj2groups = new Dictionary<string, List<string>>
{
{ "P1", new List<string>{ "Grp1" } },
{ "P2", new List<string>{ "Grp1", "Grp2" } },
};
var group2categories = new Dictionary<string, List<string>>
{
{ "Grp1", new List<string>{ "1", "11", "111" } },
{ "Grp2", new List<string>{ "2", "22", "222" } },
};
foreach (var p2g in proj2groups)
{
var projKey = p2g.Key;
foreach (var agroup in p2g.Value)
{
if (!group2categories.TryGetValue(agroup, out var categories))
continue;
if (proj2categories.ContainsKey(projKey))
proj2categories[projKey].AddRange(categories);
else
proj2categories.Add(projKey, categories);
}
}
Console.WriteLine("Expected: 3. Actual: " proj2categories["P1"].Count() " FAILED");
Console.WriteLine("Expected: 1. Actual: " proj2categories["P1"].First());
Console.WriteLine("Expected: 111. Actual: " proj2categories["P1"].Last() " FAILED");
Console.WriteLine("Expected: 6. Actual: " proj2categories["P2"].Count());
Console.WriteLine("Expected: 1. Actual: " proj2categories["P2"].First());
Console.WriteLine("Expected: 222. Actual: " proj2categories["P2"].Last());
}
}
CodePudding user response:
List is a reference type. When you assigned list for the first time , you are assigned the same list for both P1 and P2. When after this you add range to P2, as a matter of fact you add it to an existing list. This is why you have the same result. So you have assign a copy of the list to P1 and P2, this way you will have 2 independent lists. After this you can add range to independent list P2.
And I changed your algorithm to make the code more clear
foreach (var g2c in group2categories)
foreach (var p2g in proj2groups)
if (p2g.Value.Contains(g2c.Key))
{
var key = p2g.Key;
var val = g2c.Value;
if (!proj2categories.TryGetValue(key, out _))
proj2categories[key] = val.ToList();
else
proj2categories[key].AddRange(val);
}
