ChatGPT解决这个技术问题 Extra ChatGPT

How to update the value stored in Dictionary in C#?

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, only with the structs, it is because structs are returned by value, so "updating" them would update only temporary, local copy of it.

I
IT ppl

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

myDictionary[myKey] = myNewValue;

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() { { "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?
A
Amit

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

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"
m
max_force

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.


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.
C
Community

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

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.
D
Dean Seo

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

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. :)
s
saad bin sami

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

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

why not simply do dictionary[key] = value; which will simply update the value directly.
Please note that this answer is about upsert, i.e update or create. and not simply update. @Deb
V
Vlad

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


M
Mozart AlKhateeb

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.


B
BobT

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