How to update value for a specific key in a dictionary Dictionary<string, int>?
- 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;peter70– peter702018-11-16 15:03:45 +00:00Commented 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.greenoldman– greenoldman2020-11-28 06:24:42 +00:00Commented Nov 28, 2020 at 6:24
10 Answers
Just point to the dictionary at given key and assign a new value:
myDictionary[myKey] = myNewValue; 9 Comments
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
++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"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
dic.Add(key, newValue); you can use use dic[key] = newvalue;.This simple check will do an upsert i.e update or create.
if(!dictionary.TryAdd(key, val)) { dictionary[key] = val; } 3 Comments
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
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
update - modify existent only. To avoid side effect of indexer use:
int val; if (dic.TryGetValue(key, out val)) { // key exist dic[key] = val; }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
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
int is past of a struct. An update lambda would be nice.+= 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)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
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); }