List<KeyValuePair> 覆盖附加值

List<KeyValuePair> overrides added values

我目前面临一个问题,我想在 foreach 循环中向同一个键添加不同的值。

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

对于第一个工作表的第一次迭代(同时),一切都很好。如果我选择在此工作表中进行 >1 次迭代,则会添加一个新条目,但字典值都相同,f.e.:

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

如果有多次 foreach 迭代,名称保持不变,但 newSys 添加的字典键和值相同[在第二次 foreach 迭代之后]:

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"

最初我尝试使用字典,但无法正确处理相同的键,并且除了使用列表之外没有找到合适的解决方案。

非常感谢您提供的任何帮助。 如果您需要其他详细信息,请告诉我。

编辑: 期望的结果(示例):

#########:         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"

试试下面的代码:

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

     }
 }

如果您不想在键中保持任何唯一性而只想要一个平面列表,您可以使用 C#7 元组语法来构建您的列表。

List<string> sheetNames = new List<string>() { "worksheetName1", "worksheetName2" };
var sysList = new List<(string SheetName, string line1, string line2)>();

string line1 = string.Empty; 
string line2 = string.Empty; 
string quit = string.Empty;

foreach (var sheet in sheetNames)
{
    while (quit != "E")
    {
        line1 = Console.ReadLine();
        line2 = Console.ReadLine();
        quit = Console.ReadLine();

        sysList.Add((sheet, line1, line2));
    }
    quit = string.Empty;
}