有没有办法从Dictionary
删除条目(Key
)并在“同一步骤”中检索Value
?
例如,我正在打电话
Dictionary.Remove(Key);
但我也希望同时返回Value。该函数仅返回bool
。
我知道我可以做类似
的事情Value = Dictionary[Key];
Dictionary.Remove(Key);
但似乎这会搜索字典两次(一次获取值,另一次将其从字典中删除)。我怎么能(如果可能的话)两次都没有搜索字典?
答案 0 :(得分:3)
从.NET Core 2.0开始,我们有:
public bool删除(TKey键,输出TValue值);
请注意,此API尚未包含in .NET Standard 2.0和.NET Framework 4.7。
答案 1 :(得分:2)
因为他们都有所需的遗漏方法,我尝试了来自哥本哈根大学ConcurrentDictionary的微软http://www.itu.dk/research/c5/和C5,我可以告诉他,至少我的用例是超级慢(比起字典,我的意思是慢5倍 - 10倍)。
我认为C5一直在对键和值进行排序,并且“并发字典”过于担心"关于调用线程..我不是在这里讨论为什么这两个字典的化身很慢。
我的算法正在寻找和替换一些条目,而第一个键将被删除,新的密钥将被添加(某种类型的队列)...
剩下的唯一想法是修改原始.Net mscorelib的词典。我从Microsoft下载了源代码,并在我的源代码中包含了Dictionary类。要编译我还需要拖动HashHelpers类和ThrowHelper类。剩下的就是注释掉一些行(例如[DebuggerTypeProxy(typeof(Mscorlib_DictionaryDebugView<,>))]
和一些资源提取)。显然我必须将复制的类添加到缺少的方法中。另外,不要尝试编译Microsoft源代码,您将在几个小时内完成这项工作,我很幸运能够实现它。
public bool Remove(TKey key, out TValue value)
{
if (key == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
if (buckets != null)
{
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
int bucket = hashCode % buckets.Length;
int last = -1;
for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next)
{
if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
{
if (last < 0)
{
buckets[bucket] = entries[i].next;
}
else
{
entries[last].next = entries[i].next;
}
entries[i].hashCode = -1;
entries[i].next = freeList;
entries[i].key = default(TKey);
value = entries[i].value;
entries[i].value = default(TValue);
freeList = i;
freeCount++;
version++;
return true;
}
}
}
value = default(TValue);
return false;
}
最后我将命名空间修改为System.Collection.Generic.My
在我的算法中,我只有两行我获得的值而不是在下一行中删除它。用 new 方法替换它并获得7%-10%的稳定性能增益。
希望它有助于这个用例以及从头开始重新实现Dictionary的任何其他情况,而不是人们应该做的事情。
答案 2 :(得分:1)
即使这不是OP所要求的,我也无法帮助自己,但发布了更正的扩展方法:
public static bool Remove<TKey, TValue>(this Dictionary<TKey, TValue> self, TKey key, out TValue target)
{
self.TryGetValue(key, out target);
return self.Remove(key);
}
答案 3 :(得分:1)
concurrentDictionary
有一个TryRemove
方法,尝试从System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue>.
中删除并返回具有指定键的值
如果密钥不存在,则返回TValue
类型的默认值。
https://msdn.microsoft.com/en-us/library/dd287129(v=vs.110).aspx
答案 4 :(得分:-1)
您可以使用Extension方法执行此操作:
public static string GetValueAndRemove<TKey, TValue>(this Dictionary<int, string> dict, int key)
{
string val = dict[key];
dict.Remove(key);
return val;
}
static void Main(string[] args)
{
Dictionary<int, string> a = new Dictionary<int, string>();
a.Add(1, "sdfg");
a.Add(2, "sdsdfgadfhfg");
string value = a.GetValueAndRemove<int, string>(1);
}
答案 5 :(得分:-1)
您可以扩展该类以添加该功能:
public class PoppableDictionary<T, V> : Dictionary<T, V>
{
public V Pop(T key)
{
V value = this[key];
this.Remove(key);
return value;
}
}