如何在 C# 中更新存储在 Dictionary 中的值?
Posted
技术标签:
【中文标题】如何在 C# 中更新存储在 Dictionary 中的值?【英文标题】:How to update the value stored in Dictionary in C#? 【发布时间】:2010-11-17 15:22:45 【问题描述】:如何更新字典 Dictionary<string, int>
中特定键的值?
【问题讨论】:
我有一个复杂类型存储为字典中的值。当我想更改存储值的属性时,我得到 CS1612。因此我必须采取一种方法: var v = dict[c]; v.dprop = c.sprop; dict[c] = v; @peter70,只有结构体,因为结构体是按值返回的,所以“更新”它们只会更新它的临时本地副本。 【参考方案1】:只需指向给定键的字典并分配一个新值:
myDictionary[myKey] = myNewValue;
【讨论】:
所以这种简单的方法似乎也可以更好地替代众所周知的“.Add”和“.TryGetValue”方法,而无需更改值。 (?)至少,如果覆盖键并不重要,例如在不排除键在循环中多次写入的情况下。或者有人看到任何缺点吗?特别是因为 .Add 对初学者有好处,如果忘记了 if-wrapper 或 TryGetValue,它可以在测试和其他测试数据中正常工作,其中 .Add 为同一个键调用两次它会引发异常。跨度> 这个操作的有趣之处在于,它用UPSERT(key, value)转换成字典。太棒了! 正如 Pini 所说,这应该是问题的答案。由于正确的事情并改变它。 @Philm,一个巨大的缺点是,这种方法被视为修改整个字典,换句话说,它不只是更新。 @greenoldman 你确定吗?为什么要修改“整个字典”?你对你在说什么有参考吗?这肯定是字典上的一个运算符,调用一个方法做的事情完全一样......【参考方案2】:可以通过将键作为索引来访问
例如:
Dictionary<string, int> dictionary = new Dictionary<string, int>();
dictionary["test"] = 1;
dictionary["test"] += 1;
Console.WriteLine (dictionary["test"]); // will print 2
【讨论】:
如果List中没有“test”项,则list["test"] = list["test"] + 1;将引发 KeyNotFoundException!不存在的索引器的纯分配将起作用。列表[“测试”] = 1; 还能用list["test"]++;吗? 不要叫字典列表,叫它狗或猫或字典 @aufty 你可以写++dictionary["test"];
或dictionary["test"]++;
,但前提是字典中有一个键值为“test”的条目——例如:if(dictionary.ContainsKey("test")) ++dictionary["test"];
else dictionary["test"] = 1; // create entry with key "test"
【参考方案3】:
你可以按照这个方法:
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;
更新值,那么您将访问字典两次。
【讨论】:
你可以使用dic[key] = newvalue;
代替dic.Add(key, newValue);
。
如果你执行“dic[key] = value”并且“key”不存在会怎样?
@superpuccio 你得到一个 KeyNotFoundException
@ntroncos 不正确,它将使用提供的值将该键添加到字典中。 += 不适用于不存在的键,因为它只是 dic[key] = value + dic[key] 的语法糖。
这应该是问题的答案,因为它涉及更新字典而不仅仅是添加字典。【参考方案4】:
使用 LINQ:访问字典的键并更改值
Dictionary<string, int> dict = new Dictionary<string, int>();
dict = dict.ToDictionary(kvp => kvp.Key, kvp => kvp.Value + 1);
【讨论】:
我什至不明白它是如何工作的,但它很棒 为这么简单的事情创建另一本字典对我来说没有意义。检查 ccalboni 的答案。 我认为这是一个很好的答案。它不需要你知道每个键字符串 第二行(LINQ 语句)每次都会创建整个字典的副本。不是一个好主意。【参考方案5】:这是一种通过索引进行更新的方法,类似于foo[x] = 9
,其中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;
【讨论】:
m[i].Equals('1') 已经计算为布尔值,所以添加 ? true : false 是不必要的 我不知道这个逻辑有多高效,但我喜欢 For 循环的想法。 :)【参考方案6】:update - 只修改存在的。为避免使用索引器的副作用:
int val;
if (dic.TryGetValue(key, out val))
// key exist
dic[key] = val;
更新或(如果 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
【讨论】:
【参考方案7】:这个简单的检查将执行更新或创建。
if(!dictionary.TryAdd(key, val))
dictionary[key] = val;
【讨论】:
为什么不干脆做dictionary[key] = value;这将直接更新值。 请注意,这个答案是关于 upsert,即更新或创建。而不是简单地更新。 @Deb【参考方案8】:这可能对你有用:
场景 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:我用于 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;
希望对需要帮助的人有用。
【讨论】:
【参考方案9】:此扩展方法允许匹配谓词委托作为字典键选择器,并允许单独的委托执行字典值替换,因此对于所使用的键/值对的类型是完全开放的:
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]);
示例用法:
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);
【讨论】:
以上是关于如何在 C# 中更新存储在 Dictionary 中的值?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C# 中将 Dictionary<string, object> 转换为 Dictionary<string, string>