2016-04-06 9 views
0

私は文字列を倍精度にマップする辞書を持っている。それは、 が見つからない場合は、0を返し、0のデフォルト値を追加します。branchProbabilityに追加し、新しい値= 0 + branchProbability設定:辞書に項目を効率的に追加するが、代わりに+ = =

leaves[child.Value] += branchProbability; 

それが原因で代わりに行うのクラッシュ:

私はこのラインを持っていますKeyNotFoundExceptionをスローするキーを取得することから始めます。私は考えることができる

唯一のものは、次のとおりです。

if(!leaves.ContainsKey(child.Value)) 
    leaves[child.Value] = branchProbability; 
else 
    leaves[child.Value] += branchProbability; 

しかし、これは含まれていため、余分な検索が必要。

Containsチェックを回避しながらこれを行うより効率的な方法がありますか?

+2

あなたは、キーを作成して、(0.0のデフォルト値を持っているこの場合は、二重、)あなたの辞書値のために使用されるタイプのデフォルト値を返します 'TryGetValue'を使用することができます。私の意見では、あなた自身の提案された解決策ははるかに読みやすく分かりやすいです。 –

+0

また、[この回答](http://stackoverflow.com/a/2601501/717088)では、デフォルト値の拡張メソッドの作成を提案しています。同じ質問に[別の回答](http://stackoverflow.com/a/7061653/717088)があり、これは 'DefaultableDictionary'クラスの実装を作成しました。 –

答えて

2

次のコードは、+=を使用してこれを行うクラスを定義します(LinqPadに貼り付けた場合にテストします)。ただし、多くの場所に辞書を渡している場合は、newでインデクサーを非表示にする必要があります(Dictionaryのインデクサーは仮想ではありません)。これを回避するために

一つの方法は、IDictionary<TKey, TValue>の実装としてDefaultingDictionaryを作成し、クラス内Dictionaryのプライベート部材を有する、およびそれに通過IDictionary上のメソッドへのすべての呼び出しを委譲することによってだろう - を除き、インデクサー、あなたはあなた自身でやるでしょう。あなたはまだDictionaryを期待するものにこれを渡すことはできませんが、代わりにIDictionaryを受け入れるようにそれらのものを変更することができます。

void Main() 
{ 
    var dict = new DefaultingDictionary<string, double>(); 

    dict["one"] = 1; 

    dict["one"] += 1; 
    dict["two"] += 1; 

    Console.WriteLine(dict["one"]); 
    Console.WriteLine(dict["two"]); 
} 

class DefaultingDictionary<TKey, TValue> : Dictionary<TKey, TValue> 
{ 
    public new TValue this[TKey key] 
    { 
     get 
     { 
      TValue v; 
      if(TryGetValue(key, out v)) 
      { 
       return v; 
      } 
      return default(TValue); 
     } 

     set 
     { 
      base[key] = value; 
     } 
    } 
} 

正直なところ、これはちょうど+=ことを行うことができるようにすべての作業がたくさんあります。本当にあなたはただチェックするだけです。パフォーマンス上の利点はありません。コードを複雑にするだけです。あなたが小切手をしたら、それを読んでいる誰かが何が起こっているのかを正確に理解するでしょう。

-3

あなたは多分できるかどうかわかりませんが、if..elseの代わりに三項演算子を導入しても問題ありません。しかし、読みやすさの面では、あなたがやったやり方をお勧めします。

leaves[child.value] = leaves.ContainsKey(child.value) 
        ? leaves[child.value] + branchProbability 
        : branchProbability; 
関連する問題