0

次のように、 current という変数に空白値の巨大な辞書があります。

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 が発生するため、これは機能しません。ただし、値を追加または削除するのではなく、値を変更するだけなので、コードは正常に機能するはずです。しかし、私がこれを試みることを恐れている理由は理解できます。

これを行うための好ましい方法は何ですか? イテレータを使用せずに辞書をループする方法がわかりません。

配列全体のコピーを作成したくはありません。これは大量のデータであり、まだ感謝祭のように RAM を使い果たしてしまうからです。

ありがとう、デイブ

4

3 に答える 3

2

ディクショナリにキーと値の両方を同時に入力できない理由はありますか?

foreach(var key in someListOfKeys)
{
    questions.Add(key, retrieveGuess(key.userID, key.movieID);
}
于 2008-11-29T07:04:49.090 に答える
2

マットの答えは、最初にキーを取得することです。別々に行くのが正しい方法です。はい、多少の冗長性がありますが、機能します。私は、機能しないか、いつでも維持するのが難しい効率的なプログラムよりも、デバッグと維持が容易な作業プログラムを採用します。

参照型を作成すると、配列はユーザ​​ーの数だけの参照のサイズになることを忘れないでくださいMovieUser。これはかなり小さいです。x64 では、100 万人のユーザーが 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 コードに適合するように、型とメソッドの名前を大文字にします。
  • への呼び出しによって生成された を呼び出しDisposeていません。コードを使用するだけで、よりシンプル安全になります。IEnumerator<T>GetEnumeratorforeach
  • MovieUserほぼ確実にクラスになるはずです。それを構造体にする本当に正当な理由はありますか?
于 2008-11-29T07:36:08.793 に答える
0

ディクショナリ キーを一時コレクションに格納してから、一時コレクションをループし、キー値をインデクサー パラメーターとして使用します。これにより、例外を回避できます。

于 2008-11-29T07:06:10.723 に答える