2017-01-22 8 views
0

ハッシュセットを使って作業しているときに、新しいアイテムを追加しようとすることができます。アイテムが存在する場合は問題ありません。ハッシュセットは例外をスローせず、そのまま続行します。新しいアイテムを追加するときに辞書を使用するにはどうすればいいですか?

辞書では、新しい項目を追加したい場合、そのキーが存在すれば、それはスローされ、例外が発生します。それは私がdictonaryに新しい値を追加したいとき、私はいつでも、多くのコードを繰り返すことになり

Dictionary<long, List<string>> myDic = new Dictionary<long, List<string>>(); 
long myNewKey = 1; 
if(myDic.ConatainsKey(1) == false) 
{ 
    myDic.Add(1, new List<string>()); 
} 
myDic[myNewKey].Add("string01"); 
myDic[myNewKey].Add("string02"); 

:現時点では私はいつもそれを行います。 辞書を使うより良い方法があるのだろうかと思います。

拡張メソッドを作成できると思っていましたが、より良いオプションがあるかどうかを知りたいと思います。

+0

を私は、拡張メソッドは、ここで最良の選択だと思います。
も参照
http://stackoverflow.com/questions/11027369/how-to-correctly-handle-adding-new-item-to-dictionary – Piotshe

+0

より一般的な拡張サンプルはこちらhttp://stackoverflow.com/questions/3850930 /多価辞書/ 41305901#41305901 – Slai

答えて

2

(キー値のように)辞書の値のタイプによって異なります。文字列リストを指す長いキーを使用するあなたの例では、実際の問題は新しいオブジェクト値を作成する必要があることです。ディクショナリが値型(例:long-> long)を指す値型(値と参照の型のような)であった場合、インデクサ '[x]'を使用できます。キーの範囲を知っていれば、事前にバリューオブジェクトを初期化することができます。コードを減らそうとしているだけの場合は、拡張メソッドを使用してチェックを結合し、オブジェクトとセットを追加することができます。このような何か:

public static class Extensions { 
    public static void AppendToValues(this Dictionary<long, List<string>> dict, long key, string str){ 
     if (dict.ContainsKey(key)) { 
      dict.Add(key, new List<string>()); 
      } 
     dict[key].Add(str); 
     } 
    } 

次に、あなたのコード内でそのようにそれを呼び出す:

myDic.AppendToValues(myNewKey, "string01"); 
0

私がある、あなたが拡張メソッド(または辞書サブクラスなしであなたが望むものを達成できるとは思いません途中で過度の攻撃)。

あなたはここに(キーが見つからない場合は例外がスローされません)Dictionary.TryGetValueを利用し、拡張メソッドの素敵な実装を見つけることができます:

Dictionary returning a default value if the key does not exist

あなたはまだしたくない場合キーの検索は一度だけ実行されるため、拡張メソッドを使用し、TryGetValueは、より優れたパフォーマンスを提供します:

Dictionary<long, List<string>> myDic = new Dictionary<long, List<string>>(); 
long myNewKey = 1; 
List<string> list; 
if (!myDic.TryGetValue(myNewKey, out list)) 
{ 
    list = new List<string>(); 
    myDic.Add(myNewKey, list); 
} 

list.Add("string01"); 
list.Add("string02"); 
1

Dictionary<TKey,TValue>は、アイテムを追加する2つの異なる方法があります。

void Add(TKey key, TValue value)Addを呼び出しているため、あなたが言っているセマンティックは「これは存在しない、存在する」ということです。したがって、古いものか新しいものかを知ることができないため、重複挿入で例外が発生します。

インデクサー(TValue this[TKey key])は、「私がインデクサーゲッターを呼び出した場合、これを答えにしたい」という意味を持つ割り当てをサポートしています。

dict.Add(1, 1); 
var x = dict[1]; // x == 1 
dict.Add(1, 2); // throws 

dict.Add(1, 1); 
var x = dict[1]; // x == 1; 
dict[1] = 2; 
var y = dict[1]; // x == 1, y == 2. 

var dict = new Dictionary<long, int>(); 
dict[1] = 35; 
var x = dict[1]; // x == 35; 

ContainsKeyは、ほとんど常に間違ったことです。値を安全に読み取っている場合は、TryGetValueに電話してください。辞書を使用して何かが行われたかどうかを保存する場合は、HashSet<T>を使用してください。 (Addメソッドがbooltrueを追加した場合はそれが存在しませんでした)、falseが追加されなかった場合(値は既に存在しました)))を返します。

具体的には、リストに追加する場合は、TryGetValueアプローチが最適です。または、ConcurrentDictionary使用:

TryGetValue:

List<string> list; 

// Read the dictionary exactly once 
if (!dict.TryGetValue(key, out list)) 
{ 
    list = new List<string>(); 
    // Write at most once. 
    dict[key] = list; 
} 

list.Add(value); 

ConcurrentDictionary:

ConcurrentDictionary<long, List<string>> dict = new ConcurrentDictionary<long, List<string>>(); 
... 
List<string> list = dict.GetOrAdd(key,() => new List<string>()); 
list.Add(value); 
関連する問題