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

0


source to share


3 answers


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

    in IEnumerator<T>

    called by the call GetEnumerator

    . If you just use foreach

    , 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?
+2


source


Is there a reason why you can't just populate the dictionary with both keys and values ​​at the same time?



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

      

+2


source


store the dictionary keys in a temporary collection, then drill down on the temp collection and use the key value as the indexer parameter. This should result in an exception.

0


source







All Articles