2011-06-29 176 views
3

我用這個:循環在字典

foreach(KeyValuePair<String,String> entry in MyDic) 
    { 
     // do something with entry.Value or entry.Key 

    } 

的問題是,我不能改變entry.Value的價值或entry.Key

我的問題是,我怎麼能更改值或循環通過字典時的關鍵? 而且,字典是否允許重複密鑰?如果是的話,我們該如何避免? 謝謝

回答

7

雖然您可以修改該值的屬性(如果它是引用類型的實例),但您無法在循環查看字典中的項目時更改字典條目的值。

例如,

public class MyClass 
{ 
    public int SomeNumber { get; set;} 
} 

foreach(KeyValuePair<string, MyClass> entry in myDict) 
{ 
    entry.Value.SomeNumber = 3; // is okay 
    myDict[entry.Key] = new MyClass(); // is not okay 
} 

試圖修改一個字典(或任何集合),同時通過它的元素循環將導致InvalidOperationException稱集合被修改。

爲了回答您的具體問題,

我的問題是通過詞典循環時如何更改值或鑰匙?

兩者的方法幾乎相同。你可以像Anthony Pengram在his answer中說的那樣循環一本字典的副本,或者你可以遍歷所有項目,找出哪些需要修改,然後通過這些項目列表再次循環:

List<string> keysToChange = new List<string>(); 
foreach(KeyValuePair<string, string> entry in myDict) 
{ 
    if(...) // some check to see if it's an item you want to act on 
    { 
     keysToChange.Add(entry.Key); 
    } 
} 

foreach(string key in keysToChange) 
{ 
    myDict[key] = "new value"; 

    // or "rename" a key 
    myDict["new key"] = myDict[key]; 
    myDict.Remove(key); 
} 

而且,字典是否允許重複密鑰?如果是的話,我們該如何避免?

字典不允許重複鍵。如果您想收集<string, string>對,請查看NameValueCollection

+0

迭代器可以解決這個問題,就像在Java中的地圖迭代器? – Xitrum

+0

@ user552279如果我記得正確,'foreach'在幕後調用一個迭代器,並且假設集合必須保持不變。這裏有一個解釋[這裏](http://stackoverflow.com/questions/4536090/collection-was-modified-enumeration-operation-may-not-execute-why)。 Anthony的答案會起作用,因爲它會創建一個可以迭代的字典副本,然後修改原始集合。 –

0

KeyValuePair的密鑰和值是隻讀的。但你可以改變這樣的值:

dictionary[key].Value = newValue; 

但是如果你想改變密鑰,你將不得不刪除/添加一個密鑰。

不,一個字典不允許重複的鍵,它會拋出一個ArgumentException。

+0

但如果我的鑰匙是字符串?那麼如何通過字典循環? – Xitrum

6

更新循環中的字典將成爲一個問題,因爲您不能修改它正在被枚舉的字典。但是,您可以通過將字典轉換爲一個KeyValuePair<>對象列表來輕鬆解決這個問題。您列舉該列表,然後您可以修改字典。

foreach (var pair in dictionary.ToList()) 
{ 
    // to update the value 
    dictionary[pair.Key] = "Some New Value"; 

    // or to change the key => remove it and add something new 
    dictionary.Remove(pair.Key); 
    dictionary.Add("Some New Key", pair.Value); 
} 

對於第二部分,字典中的鍵必須是唯一的。

+0

這是正確答案 – jjxtra

+1

@user,您的評論「爲什麼我看不到ToList()」 - >這是Linq的一部分,它在C#3 +中可用。如果你正在使用這樣的版本,你可以在你的代碼文件中添加一個'using System.Linq;'語句(也假定你的項目中有一個引用System.Core.dll,在新項目中默認引用它) 。 –

-2

你可以做到這一點像

for (int i = 0; i < MyDic.Count; i++) 
{ 
    KeyValuePair<string, string> s = MyDic.ElementAt(i); 
    MyDic.Remove(s.Key); 
    MyDic.Add(s.Key, "NewValue"); 
} 

和詞典不允許重複

+0

根據下面的實現,枚舉時修改集合可能會產生不良結果... – jjxtra

+0

@JJC:我同意。 – Anuraj

+1

@Anuraj這將拋出一個InvalidOperationException。 –

0

同時列舉他們不能修改鍵。

一種方法我用了修改集合枚舉時他們是我做break;foreach循環的時候找到一個匹配和項目被修改,和我一遍重啓整個枚舉。這是處理它的一種方法...

不,字典不能有重複的鍵。如果你想要按鍵排序並允許重複的東西,你應該使用其他數據結構。