681

How to update value for a specific key in a dictionary Dictionary<string, int>?

2
  • I have a complex type stored as value in dictionary. When I want to change a property of an stored value, I get CS1612. Therefore I must take a way around: var v = dict[c]; v.dprop = c.sprop; dict[c] = v; Commented Nov 16, 2018 at 15:03
  • @peter70, only with the structs, it is because structs are returned by value, so "updating" them would update only temporary, local copy of it. Commented Nov 28, 2020 at 6:24

10 Answers 10

1070

Just point to the dictionary at given key and assign a new value:

myDictionary[myKey] = myNewValue; 
Sign up to request clarification or add additional context in comments.

9 Comments

the interesting point of this operation is that, it UPSERT (key, value) into dictionary. brilliant!
As Pini stated, this should be the answer to the question. due the right thing and change it.
@Philm, one huge disadvantage is, this approach is treated as modifying entire dictionary, in other words it is not just an update.
@nevelis, var dict = new Dictionary<string,int>() { { "a" , 0 }, { "b", 0 }, }; foreach (var key in dict.Keys) dict[key] = 1; } } If it was merely an update of the value you wouldn't get exception when iterating over keys, because superficially one has nothing to do with the other.
@greenoldman ahh I see what you mean, I misunderstood what you meant by “modifying the whole dictionary” you are referring to it invalidating any current iterator right?
|
221

It's possible by accessing the key as index

for example:

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

3 Comments

If there is no item "test" in the List, then list["test"] = list["test"] + 1; will raise KeyNotFoundException! The pure assignment of a non existing indexer will work. list["test"] = 1;
Can you also use list["test"]++;?
@aufty you can write ++dictionary["test"]; or dictionary["test"]++; but only if there is an entry in the dictionary with the key value "test" — example: if(dictionary.ContainsKey("test")) ++dictionary["test"]; else dictionary["test"] = 1; // create entry with key "test"
65

You can follow this approach:

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); } } 

The edge you get here is that you check and get the value of corresponding key in just 1 access to the dictionary. If you use ContainsKey to check the existance and update the value using dic[key] = val + newValue; then you are accessing the dictionary twice.

9 Comments

Instead of dic.Add(key, newValue); you can use use dic[key] = newvalue;.
What happens if you do "dic[key] = value" and "key" doesn't exist?
@superpuccio you get a KeyNotFoundException
@ntroncos not true, it will add that key to the dictionary with the value provided. += will not work on a non-existing key though, since it is just syntactic sugar for dic[key] = value + dic[key].
This should be the answer to the question as it regards updating the dictionary not just adding to it.
|
22

This simple check will do an upsert i.e update or create.

if(!dictionary.TryAdd(key, val)) { dictionary[key] = val; } 

3 Comments

why not simply do dictionary[key] = value; which will simply update the value directly.
Because if you simply do: dictionary[key] = value; then you will be overwriting the value each time. Considering the fact that your dictionaries can be static and shared across different threads, and overwriting may require a lock, i would prefer to first check whether the key/value exists or not? if not, then only then we should update it. @Deb
What if you want to modify the already stored value instead of just replacing it. A Lambda to do that would be nice.
18

Use LINQ: Access to dictionary for the key and change the value

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

4 Comments

I don't even understand how this works but it's amazing
Creating another dictionary doesn't make sense to me for such simple thing. Check ccalboni's answer.
i think it is a good answer. it doesn't require you to know each key string
Second line (LINQ statement) will create copy of whole dictionary each time. Not a good idea.
11

Here is a way to update by an index much like foo[x] = 9 where x is a key and 9 is the value

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; } } 

2 Comments

the m[i].Equals('1') already evaluates to a bool, so adding ? true : false is not necessary
I dont know how efficient is this logic, but I like the For loop idea. :)
3
  1. update - modify existent only. To avoid side effect of indexer use:

    int val; if (dic.TryGetValue(key, out val)) { // key exist dic[key] = val; } 
  2. update or (add new if value doesn't exist in dic)

    dic[key] = val; 

    for instance:

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

Comments

2

You Can Also Use This Method :

Dictionary<int,int> myDic = new(); if (myDic.ContainsKey(1)) { myDic[1] = 1234; // or use += to update it } 

Or By Value :

if (myDic.ContainsValue(1)) { //do something ... } 

2 Comments

That replaces the existing value. What if I need to increase the value? What if the int is past of a struct. An update lambda would be nice.
@Martin i mentioned in the code comment that using += you can increase the value, basically myDic[X] is a reference to your values so you can do whatever you want with it as long as it doesnt cause exceptions (invalid index ..etc)
1

This may work for you:

Scenario 1: primitive types

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; 

Scenario 2: The approach I used for a List as Value

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; 

Hope it's useful for someone in need of help.

Comments

0

This extension method allows a match predicate delegate as the dictionary key selector, and a separate delegate to perform the dictionary value replacement, so it's completely open as to the type of key/value pair being used:

public static void UpdateAll<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, Func<TKey, TValue, bool> matchPredicate, Func<TValue, TValue> updatePredicate) { var keys = dictionary.Keys.Where(k => matchPredicate(k, dictionary[k])).ToList(); foreach (var key in keys) { dictionary[key] = updatePredicate(dictionary[key]); } } 

Example usage:

 Dictionary<int, string> dict = new Dictionary<int, string>(); dict.Add(1, "One"); dict.Add(2, "Two"); dict.Add(3, "Three"); //Before foreach(var kvp in dict){ Console.WriteLine(kvp.Value); } dict.UpdateAll( matchPredicate: (k, v) => k >= 2, //Update any dictionary value where the key is >= 2 updatePredicate: (v) => v = v + " is greater than One" ); //After foreach(var kvp in dict){ Console.WriteLine(kvp.Value); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.