C# .net字典和查找添加/更新
我厌倦了对我拥有的各种代码位执行这样的代码块:C# .net字典和查找添加/更新,c#,collections,C#,Collections,我厌倦了对我拥有的各种代码位执行这样的代码块: if (dict.ContainsKey[key]) { dict[key] = value; } else { dict.Add(key,value); } 和用于查找(即键->值列表) 我不确定是否有你要求的方法,但是你可以为它编写一个小函数,或者使用try-catch异常,如果你尝试添加一个已经存在的值,它可能会抛出一个异常。如果你抓住了它而忽略了它。。。只是.NET4.0中ConcurrentDicti
if (dict.ContainsKey[key]) {
dict[key] = value;
}
else {
dict.Add(key,value);
}
和用于查找(即键->值列表)
我不确定是否有你要求的方法,但是你可以为它编写一个小函数,或者使用try-catch异常,如果你尝试添加一个已经存在的值,它可能会抛出一个异常。如果你抓住了它而忽略了它。。。只是.NET4.0中ConcurrentDictionary的一个建议。您也可以为此编写扩展方法。更新时,您不需要执行检查。只需使用:
dict[key] = value
它将替换任何现有值。不幸的是,在检索值时,没有方便的单一方法(如Python中的setdefault
),但您可以创建自己的扩展方法。大概是这样的:
if (!lookup.TryGetValue(key, out value))
{
value = new List<T>();
lookup.Add(key, value);
}
if(!lookup.TryGetValue(键,输出值))
{
值=新列表();
查找。添加(键、值);
}
正如Evgeny所说,索引器已经替换了现有的值-因此,如果您只想无条件地设置给定键的值,您可以这样做
dictionary[key] = value;
更有趣的例子是“获取一个值,或者在必要时插入它”。使用扩展方法很容易:
public static TValue GetOrCreateValue<TKey, TValue>
(this IDictionary<TKey, TValue> dictionary,
TKey key,
TValue value)
{
return dictionary.GetOrCreateValue(key, () => value);
}
public static TValue GetOrCreateValue<TKey, TValue>
(this IDictionary<TKey, TValue> dictionary,
TKey key,
Func<TValue> valueProvider)
{
TValue ret;
if (!dictionary.TryGetValue(key, out ret))
{
ret = valueProvider();
dictionary[key] = ret;
}
return ret;
}
公共静态TValue GetOrCreateValue
(这本词典,
TKey键,
t价值(价值)
{
返回dictionary.GetOrCreateValue(键,()=>value);
}
公共静态TValue GetOrCreateValue
(这本词典,
TKey键,
Func值提供程序)
{
TValue-ret;
if(!dictionary.TryGetValue(key,out-ret))
{
ret=valueProvider();
字典[键]=ret;
}
返回ret;
}
注意使用委托来创建默认值,这有助于实现“列表为值”这样的场景;您不想创建空列表,除非您必须:
dict.GetOrCreateValue(key, () => new List<int>()).Add(item);
dict.GetOrCreateValue(键,()=>newlist())。添加(项);
还要注意的是,如果键已经存在,这只执行一次查找-不需要执行
ContainsKey
然后查找值。但是,在创建新值时,它仍然需要两次查找。如果使用.NET Framework 4或更高版本,您可以使用
添加或更新是这样的
dict[key] = value;
我喜欢的方法,但我也喜欢字典集合的性能:)所以,这是所有实现类的扩展方法
publicstatictvalue AddOrUpdate(
这是我的字典,
TKey键,
TValue附加值,
Func更新值(工厂)
{
价值存在;
if(dict.TryGetValue(键,不存在))
{
addValue=updateValueFactory(键,现有);
dict[key]=addValue;
}
其他的
{
dict.Add(key,addValue);
}
返回附加值;
}
公共静态TValue AddOrUpdate(
这是我的字典,
TKey键,
Func addValueFactory,
Func更新值(工厂)
{
价值存在;
if(dict.TryGetValue(键,不存在))
{
现有=updateValueFactory(键,现有);
dict[key]=现有;
}
其他的
{
现有=addValueFactory(键);
dict.Add(键,现有);
}
返回现有的;
}
这仅适用于ConcurrentDictionary
是的,您可以将其与Concurrent Dictionary一起使用,因为您不想陷入这样的陷阱:检查添加条件,确定需要执行添加,然后让其他人在背后执行添加。我相信AddOrUpdate使它原子化了。lookup
是ILookup
?我这么想不是因为它不应该有ContainsKey
方法。仅确认.NET并没有更改自问题提出以来的查找,因为它正在寻找更新ILookup
的方法。。。
dict.GetOrCreateValue(key, () => new List<int>()).Add(item);
dict.AddOrUpdate(key,value)
dict[key] = value;
public static TValue AddOrUpdate<TKey, TValue>(
this IDictionary<TKey, TValue> dict,
TKey key,
TValue addValue,
Func<TKey, TValue, TValue> updateValueFactory)
{
TValue existing;
if (dict.TryGetValue(key, out existing))
{
addValue = updateValueFactory(key, existing);
dict[key] = addValue;
}
else
{
dict.Add(key, addValue);
}
return addValue;
}
public static TValue AddOrUpdate<TKey, TValue>(
this IDictionary<TKey, TValue> dict,
TKey key,
Func<TKey, TValue> addValueFactory,
Func<TKey, TValue, TValue> updateValueFactory)
{
TValue existing;
if (dict.TryGetValue(key, out existing))
{
existing = updateValueFactory(key, existing);
dict[key] = existing;
}
else
{
existing = addValueFactory(key);
dict.Add(key, existing);
}
return existing;
}