Hopefully simple question about changing dictionaries in C #
I have a huge dictionary of empty values ββin a variable called current like so:
struct movieuser {blah blah blah}
Dictionary<movieuser, float> questions = new Dictionary<movieuser, float>();
So, I go through this dictionary and have to fill in the "answers" like:
for(var k = questions.Keys.GetEnumerator();k.MoveNext(); )
{
questions[k.Current] = retrieveGuess(k.Current.userID, k.Current.movieID);
}
Now this doesn't work because I am getting InvalidOperationException from trying to change the dictionary I am iterating over. However, you can see that the code should work fine - since I am not adding or removing any values, just changing the value. I understand, however, why he is afraid that I will try to do this.
What's the preferred way to do this? I cannot find a way to scroll through the dictionary WITHOUT using iterators.
I really do not want to create a copy of the entire array as this is a lot of data and it will eat my ram like its still Thanksgiving.
Thanks, Dave
source to share
Matt responds by getting the keys first, separately - that's the right way. Yes, there will be some redundancy - but it will work. I would take a working program that is easy to debug and supports a more efficient program that either won't work or will be difficult to maintain on any given day.
Don't forget that if you create a reference type MovieUser
, the array will only be as large as as many references as you have - that's pretty small. A million users will only take 4 MB or 8 MB on x64. How many users do you have?
Therefore, your code should look something like this:
IEnumerable<MovieUser> users = RetrieveUsers();
IDictionary<MovieUser, float> questions = new Dictionary<MovieUser, float>();
foreach (MovieUser user in users)
{
questions[user] = RetrieveGuess(user);
}
If you are using .NET 3.5 (and therefore can use LINQ) this is even easier:
IDictionary<MovieUser, float> questions =
RetrieveUsers.ToDictionary(user => user, user => RetrieveGuess(user));
Note that if it RetrieveUsers()
can pass a list of users from its source (like a file), then it will be efficient anyway, as you should never be aware of more than one of them while you are populating a dictionary.
A few comments on the rest of your code:
- The conventions are justified. Name your types and methods to fit in with other .NET code.
- You are not calling
Dispose
inIEnumerator<T>
called by the callGetEnumerator
. If you just useforeach
, your code will be simpler and safer. -
MovieUser
should almost certainly be a class. Do you have a really good reason for creating a structure?
source to share