【问题标题】:List<KeyValuePair> overrides added valuesList<KeyValuePair> 覆盖添加的值
【发布时间】:2020-07-29 14:22:39
【问题描述】:

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

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

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

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

如果有多次foreach迭代,名称保持不变,但newSys添加的Dictionary Key和Values相同[在第二次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"

【问题讨论】:

  • 您需要更新newSystem。你不能只是清除它然后重新添加它。newSystem是一个参考,所以你对它所做的一切,都是对列表中的所有项目完成的。
  • @jdweng:我很难在每次迭代中正确地将值添加到该列表中。我不知道如何在我的 foreach 循环中添加值。
  • @julezQ 如果您将newSystem 字典的声明移动到foreach 循环中,它将解决您的问题。但是你的代码对我来说看起来很奇怪。为什么将dictionary 用于newSystem?为什么在 while 循环的每次迭代中都清除它?
  • @Palle Due 感谢您的帮助,我将 newSystem 放在了 while -Loop 之前。在同一个工作表中它现在正在工作,但不幸的是,如果下一次迭代发生,它会覆盖之前的所有值。我错过了什么?
  • 我有一个错字。请参阅以下内容:您不需要字典。可以使用 :List>>> kvp = new List>>>();或使用字典 Dictionary>> 当一个键有多个值时,字典中的值需要是一个列表。

标签: c# .net .net-core keyvaluepair


【解决方案1】:

如果您不想在键中保持任何唯一性而只想要一个平面列表,则可以使用 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;
}

【讨论】:

    【解决方案2】:

    试试下面的代码:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-17
      • 1970-01-01
      相关资源
      最近更新 更多