每次迭代后,C#字典都会保留擦除值

时间:2012-06-28 17:19:43

标签: c# list dictionary

所以我有一个问题......我正在尝试将HTML格式的5个左右的双语词典合并成一个单一的多语言词典,并以英语作为源语言。为此,我决定设置一个字典,并将每个非英语单词映射到它的英语对应单词(键)[见下面的代码]。

1 public void ConsolidateDictionary(string directoryPath)
2 {
3    DirectoryInfo directory = new DirectoryInfo(directoryPath);
4    string key = string.Empty;
5    string value = string.Empty;
6    Dictionary<string, List<string>> languages = 
         new Dictionary<string, List<string>>();
7    List<string> temp = new List<string>();
8    foreach (FileInfo file in directory.EnumerateFiles())
9    {
10       HtmlDocument doc = new HtmlDocument();
11       doc.Load(file.FullName);
12
13       foreach (HtmlNode node in doc.DocumentNode.SelectNodes(".//wordunit"))
14       {
15          foreach (HtmlNode child in node.SelectNodes(".//word"))
16           {
17                   if (child.Attributes["language"].Value == "EN")
18                   {
19                       key = child.OuterHtml.ToString();
20                   }
21                   else
22                   {
23                       value = child.OuterHtml.ToString();
24                   }
25           }
26
27           if (key != null && value != null)
28           {
29               if (languages.ContainsKey(key))
30               {
31                   foreach (var item in languages[key])
32                   {
33                       temp.Add(item);
34                   }
35                   temp.Add(value);
36                   languages.Remove(key);
37                   languages.Add(key, temp);
38                   temp.Clear();
39               }
40               else
41               {
42                       temp.Add(value);
43                       languages.Add(key, temp);
44                       temp.Clear();
45               }
46           }
47       }
48   }
49   WriteFile(languages);
50 }

基本上发生的事情是,在第15行的foreach循环的每次迭代之后,现有的字典值都被清零(但是键保持不变)。所以,假设在第15行循环的第一次迭代之后,字典(称为“语言”)包含:key: <word language="EN">Hello</word> Value: <word language="ES">Hola</word>;当第二次迭代出现时,该值将从字典“languages”中删除,只留下:

key: <word language="EN">Hello</word>
Value: null
key: <word language="EN">Goodbye</word>
Value: <word language="ES">Chao</word>

(其中Goodbye-Chao对作为第二次迭代的键值对传入)。

可能导致这种奇怪行为的原因......据我所知,我根本不会覆盖字典中的值!有谁知道我哪里出错了?

2 个答案:

答案 0 :(得分:3)

temp.Add(value);
 //languages.Add(key, temp);
temp.Clear();

看看你对那个糟糕的List实例做了些什么。为每个密钥使用新的List实例。


if (!languages.ContainsKey(key))
{
  languages.Add(key, new List<string>())
}
languages[key].Add(value);

答案 1 :(得分:2)

您正在为每个键设置临时值。您希望每次分配时都为temp创建一个新对象。一旦你打电话给清楚,你就会在每件物品上擦拭它。

您在整个时间使用相同的列表。因此,您将项目添加到第一个键,然后清除它。这将清除你投入该值的所有内容。

修正:

public void ConsolidateDictionary(string directoryPath)
{
   DirectoryInfo directory = new DirectoryInfo(directoryPath);
   string key = string.Empty;
   string value = string.Empty;
   Dictionary<string, List<string>> languages = new Dictionary<string, List<string>>();
   List<string> temp = null;
   foreach (FileInfo file in directory.EnumerateFiles())
   {
       HtmlDocument doc = new HtmlDocument();
       doc.Load(file.FullName);

       foreach (HtmlNode node in doc.DocumentNode.SelectNodes(".//wordunit"))
       {
          foreach (HtmlNode child in node.SelectNodes(".//word"))
           {
                   if (child.Attributes["language"].Value == "EN")
                   {
                       key = child.OuterHtml.ToString();
                   }
                   else
                   {
                       value = child.OuterHtml.ToString();
                   }
           }

           if (key != null && value != null)
           {
               if (languages.ContainsKey(key))
               {
                if(languages[key].Items.Contains(value) == false)
                         languages[key].Add(value);
               }
               else
               {
                    languages.Add(key, new List<string>);
                    languages[key].Add(value);
               }
           }
       }
   }
   WriteFile(languages);
 }