2012-06-28 44 views
0

所以我遇到了一個問題......我試圖將5種左右的雙語詞典以HTML格式整合到一個單一的多語言字典中,並使用英語作爲源語言。爲此,我決定設置一本詞典,並將每個非英語單詞映射到它的英文單詞(鍵)[見下面的代碼]。C#字典在每次迭代後都保持擦除值

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>;當在第二次迭代來臨時,該值被從字典「語言」去除,只留下:

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

(其中再見超對被傳遞在作爲鍵 - 值對的第二次迭代)。

什麼可能導致這種奇怪的行爲......據我所知,我不會覆蓋我的字典中的值!有沒有人知道我要去哪裏錯了?

+0

大衛和傑里米的答案之後,我覺得這是值得的注意的是,在C#中,字典不創建一個變量的工作副本......其實,它只是引用所述變量,所以對變量所做的任何更改都會反映在Dictionary中。我知道這看起來很直觀(特別是在事實之後),但是,我沒有看到它,而且可能有其他人可能會掛斷電話。 – gfppaste

回答

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

這是正確的,但它不回答爲什麼邏輯有缺陷的問題。 –

+0

只有一個列表實例。該列表實例已被Clear調用。還有什麼要解釋的? –

+0

查看我的答案 - 字節點上的循環需要擴展,以包含字典中存在的(不可否認的)檢查。 –

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