2008-11-29 51 views
0

我具有空值的變量中一個巨大的字典稱爲當前像這樣:約在C#修改詞典希望簡單的問題

struct movieuser {blah blah blah} 
Dictionary<movieuser, float> questions = new Dictionary<movieuser, float>(); 

因此,我通過這本詞典循環,需要填寫「答案」 ,像這樣:

for(var k = questions.Keys.GetEnumerator();k.MoveNext();) 
{ 
    questions[k.Current] = retrieveGuess(k.Current.userID, k.Current.movieID); 
} 

現在,這是不行的,因爲我是從試圖修改我循環通過字典得到一個InvalidOperationException。但是,您可以看到代碼應該正常工作 - 因爲我不添加或刪除任何值,只是修改該值。不過,我明白爲什麼它害怕我嘗試這個。

這樣做的首選方式是什麼?我無法找出一種方法來循環使用字典而不使用迭代器。

我真的不想創建整個數組的副本,因爲它是大量的數據,並會像我的感恩節一樣吃掉我的內存。

謝謝, 戴夫

+0

想過更多之後,我不能編輯值的原因是因爲字典將它存儲在某種不斷變化的二叉樹或其他東西中?在這種情況下,如果你改變了值,它可能會改變列表的順序,與迭代器搞砸...... – 2008-11-29 07:10:45

+0

在這種情況下,我認爲有必要創建一個臨時數組鍵......但我仍然不相信這是事實。 – 2008-11-29 07:11:47

回答

2

馬特的答案,首先得到鑰匙,分開是正確的路要走。是的,會有一些冗餘 - 但它會起作用。我會選擇一個易於調試的工作程序,並且可以維護一個高效的程序,這個程序不會運行或者很難維護。

不要忘記,如果您製作MovieUser引用類型,該數組將只有您獲得用戶的引用數量的大小 - 這非常小。一百萬用戶只能在x64上佔用4MB或8MB的空間。你有多少用戶?

您的代碼因此應該是這樣的:

IEnumerable<MovieUser> users = RetrieveUsers(); 

IDictionary<MovieUser, float> questions = new Dictionary<MovieUser, float>(); 
foreach (MovieUser user in users) 
{ 
    questions[user] = RetrieveGuess(user); 
} 

如果你使用.NET 3.5(因此可以使用LINQ),那就更簡單了:

IDictionary<MovieUser, float> questions = 
    RetrieveUsers.ToDictionary(user => user, user => RetrieveGuess(user)); 

注意,如果RetrieveUsers()可以從源文件中(例如文件)流式傳輸用戶列表,那麼無論如何它都會很高效,因爲在填充字典時,您一次不需要知道其中多個用戶。

你的代碼的其餘部分需要注意幾點:

  • 編碼規範的問題。大寫您的類型和方法的名稱以適應其他.NET代碼。
  • 你不致電DisposeIEnumerator<T>致電GetEnumerator產生。如果你只是使用foreach你的代碼會更簡單更安全。
  • MovieUser應該幾乎可以肯定是一個類。你有一個真正的理由讓它成爲一個結構?
2

是否有任何理由你可以填充不同時鍵和值的字典?

foreach(var key in someListOfKeys) 
{ 
    questions.Add(key, retrieveGuess(key.userID, key.movieID); 
} 
+0

可能,但你有記憶問題字典加上一些鍵列表 - 這是多餘的。感謝您的快速反應! – 2008-11-29 07:07:23

0

將字典鍵存儲在臨時集合中,然後遍歷臨時集合並將鍵值用作索引器參數。這應該引起你的注意。