C#のディクショナリに格納されている値を更新する方法


455

辞書の特定のキーの値を更新する方法はDictionary<string, int>


辞書に値として格納されている複合型があります。格納された値のプロパティを変更したい場合、CS1612を取得します。したがって、回避策を講じる必要があります。var v = dict [c]; v.dprop = c.sprop; dict [c] = v;
peter70

回答:


762

与えられたキーでディクショナリをポイントし、新しい値を割り当てます。

myDictionary[myKey] = myNewValue;

したがって、この単純なメソッドは、値を変更する必要なしに、よく知られている「.Add」および「.TryGetValue」メソッドのより良い代替品のようです。(?)少なくとも、キーを上書きする必要がない場合(たとえば、ループ内でキーが複数回書き込まれることが除外されていない場合など)。または誰かが何か不利な点を見ますか?特に、.Addには初心者向けの落とし穴があるため、if-wrapperまたはTryGetValueを忘れると、テストで正常に機能し、同じキーに対して.Addが2回呼び出される他のテストデータでは例外がスローされます。
Philm

1
この操作の興味深い点は、辞書へのUPSERT(キー、値)です。鮮やかさ!
Soren

1
ピニが述べたように、これが質問への答えになるはずです。正しいことにより、それを変更します。
レオグルディアン2017年

190

インデックスとしてキーにアクセスすることで可能です

例えば:

Dictionary<string, int> dictionary = new Dictionary<string, int>();
dictionary["test"] = 1;
dictionary["test"] += 1;
Console.WriteLine (dictionary["test"]); // will print 2

11
リストに項目「test」がない場合、list ["test"] = list ["test"] + 1; KeyNotFoundExceptionが発生します!存在しないインデクサーの純粋な割り当てが機能します。list ["test"] = 1;
Steven Spyrka

list ["test"] ++;も使用できますか?
2

17
辞書リストを呼び出さず、犬、猫、または辞書と呼ぶ
user3800527

1
@aufty書き込み可能、++dictionary["test"];またはdictionary["test"]++;辞書にキー値「test」のエントリがある場合のみ—例: if(dictionary.ContainsKey("test")) ++dictionary["test"]; else dictionary["test"] = 1; // create entry with key "test"
gerryLowry

46

このアプローチに従うことができます:

void addOrUpdate(Dictionary<int, int> dic, int key, int newValue)
{
    int val;
    if (dic.TryGetValue(key, out val))
    {
        // yay, value exists!
        dic[key] = val + newValue;
    }
    else
    {
        // darn, lets add the value
        dic.Add(key, newValue);
    }
}

ここで得られる利点は、辞書に1回アクセスするだけで、対応するキーの値を確認して取得できることです。を使用ContainsKeyして存在を確認し、値を更新するdic[key] = val + newValue;場合は、辞書に2回アクセスしています。


4
代わりにdic.Add(key, newValue);useを使用できますdic[key] = newvalue;
マッケ2015

「dic [key] = value」を実行し、「key」が存在しない場合はどうなりますか?
superpuccio

1
@superpuccioはKeyNotFoundException
ntroncos

8
@ntroncosは真ではありません。指定された値でそのキーを辞書に追加します。+ =はdic [key] = value + dic [key]の単なる構文糖なので、存在しないキーでは機能しません。
lastas

2
これは、辞書を追加するだけでなく、辞書を更新することに関する質問の答えになるはずです。
ロンリーコーダー、

15

LINQを使用:キーのディクショナリへのアクセスと値の変更

Dictionary<string, int> dict = new Dictionary<string, int>();
dict = dict.ToDictionary(kvp => kvp.Key, kvp => kvp.Value + 1);

私もどのようにこの作品を理解していないが、それは驚くべきことだ
hexagonest

1
別の辞書を作成しても、そんな単純なことでは意味がありません。ccalboniの答えを確認してください。
RollerCosta 2017

1
いい答えだと思います。各キー文字列を知っている必要はありません
Joseph Wu

9

foo[x] = 9where xがキーで9が値のようにインデックスで更新する方法は次のとおりです

var views = new Dictionary<string, bool>();

foreach (var g in grantMasks)
{
    string m = g.ToString();
    for (int i = 0; i <= m.Length; i++)
    {
        views[views.ElementAt(i).Key] = m[i].Equals('1') ? true : false;
    }
}

13
m [i] .Equals( '1')はすでにブールに評価されるので、?true:falseは必要ありません
ウェッセルファンデルリンデン

このロジックの効率はわかりませんが、Forループのアイデアが好きです。:)
オープンおよび無料

2
  1. 更新 -存在のみを変更します。インデクサー使用の副作用を回避するには:

    int val;
    if (dic.TryGetValue(key, out val))
    {
        // key exist
        dic[key] = val;
    }
  2. 更新または(値がdicに存在しない場合は新規に追加

    dic[key] = val;

    例えば:

    d["Two"] = 2; // adds to dictionary because "two" not already present
    d["Two"] = 22; // updates dictionary because "two" is now present

1

これはあなたのために働くかもしれません:

シナリオ1:プリミティブ型

string keyToMatchInDict = "x";
int newValToAdd = 1;
Dictionary<string,int> dictToUpdate = new Dictionary<string,int>{"x",1};

if(!dictToUpdate.ContainsKey(keyToMatchInDict))
   dictToUpdate.Add(keyToMatchInDict ,newValToAdd );
else
   dictToUpdate[keyToMatchInDict] = newValToAdd; //or you can do operations such as ...dictToUpdate[keyToMatchInDict] += newValToAdd;

シナリオ2:リストを値として使用するアプローチ

int keyToMatch = 1;
AnyObject objInValueListToAdd = new AnyObject("something for the Ctor")
Dictionary<int,List<AnyObject> dictToUpdate = new Dictionary<int,List<AnyObject>(); //imagine this dict got initialized before with valid Keys and Values...

if(!dictToUpdate.ContainsKey(keyToMatch))
   dictToUpdate.Add(keyToMatch,new List<AnyObject>{objInValueListToAdd});
else
   dictToUpdate[keyToMatch] = objInValueListToAdd;

助けが必要な人に役立つことを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.