Search code examples
c#.net.net-corekeyvaluepair

List<KeyValuePair> overrides added values


I am currently facing an issue where I want to add different values to the same Key in a foreach loop.

List<KeyValuePair<string, Dictionary<string, string>>> sysList = new List<KeyValuePair<string, Dictionary<string, string>>>();
Dictionary<string, string> newSystem = new Dictionary<string, string>();
string line1="";
string line2="";
string quit="";
foreach(Worksheet ws in workbook.Worksheets)
{
     while(quit != q)
     {
        newSystem.Clear();
        line1 = Console.ReadLine();
        line2 = Console.ReadLine();
        quit = Console.ReadLine();
     }
     newSystem.Add(line1, line2);
     sysList.Add(new KeyValuePair<string, Dictionary<string, string>>(ws.Name,newSystem));
}

For the first iteration (within while) of the first Worksheet ws everything is fine. If the I choose to do >1 iterations within this Worksheet, there is a new entry added, but the Dictionary values are all the same, f.e.:

syList[0]: "worksheetName","test1","test2"
syList[1]: "worksheetName","test1","test2"
syList[2]: "worksheetName","test1","test2"

If there are several foreach iterations, the names stay the same, but the Dictionary Key and Values added by newSys are the same [AFTER the second foreach iteration]:

syList[0]: "worksheetName1","test1","test2"
syList[1]: "worksheetName1","test1","test2"
syList[2]: "worksheetName1","test1","test2"
syList[3]: "worksheetName2","test1","test2"
syList[4]: "worksheetName2","test1","test2"

Initially I tried using Dictionaries, but could not handle the same keys properly and did not find a proper solution except for using List.

I am very grateful for any help provided. If there are additional details that you require, please, let me know.

Edit: desired result (example):

#########:         ws.Name, line1,   line2
syList[0]: "worksheetName1","ABC","1"
syList[1]: "worksheetName1","DEF","2"
syList[2]: "worksheetName1","ABC","5"
syList[3]: "worksheetName2","ABD","4"
syList[4]: "worksheetName2","ZZZ","1"

Solution

  • Try code below :

    List<List<string>> syList =  new List<List<string>>() {
                                    new List<string>() {"worksheetName1","test1","test2"},
                                    new List<string>() {"worksheetName1","test1","test2"},
                                    new List<string>() {"worksheetName1","test1","test2"},
                                    new List<string>() {"worksheetName2","test1","test2"},
                                    new List<string>() {"worksheetName2","test1","test2"}
                        };
     Dictionary<string, Dictionary<string, List<string>>> dict = syList
        .GroupBy(x => x.First(), y => y)
            .ToDictionary(x => x.Key, y => y
                .GroupBy(a => a.Skip(1).FirstOrDefault(), b => b.Last())
                .ToDictionary(a => a.Key, b => b.ToList()));
    
    
    //using normal looping
     Dictionary<string, Dictionary<string, List<string>>> dict2 = new Dictionary<string, Dictionary<string, List<string>>>();
    
     foreach (List<string> sy in syList)
     {
         if (dict2.ContainsKey(sy[0]))
         {
             Dictionary<string, List<string>> tempDict = dict2[sy[0]];
             if (tempDict.ContainsKey(sy[1]))
             {
                 tempDict[sy[1]].Add(sy[2]);
             }
             else
             {
                 List<string> newList = new List<string>() { sy[2] };
                 tempDict.Add(sy[1], newList);
    
             }
         }
         else
         {
             Dictionary<string, List<string>> newDict = new Dictionary<string, List<string>>();
             newDict.Add(sy[1], new List<string> { sy[2] });
             dict2.Add(sy[0], newDict);
    
         }
     }