有没有一种方法可以在同一步骤中通过Key
删除Dictionary
中的一个条目并检索其Value
?
例如,我正在调用
Dictionary.Remove(Key);
但我也希望它同时返回值。该函数仅返回一个bool
。
我知道我可以像下面这样做:
Value = Dictionary[Key];
Dictionary.Remove(Key);
但似乎这将搜索两次字典(一次获取值,另一次从字典中删除)。如果可能的话,我该如何同时完成这两个操作而不需要搜索两次字典?
有没有一种方法可以在同一步骤中通过Key
删除Dictionary
中的一个条目并检索其Value
?
例如,我正在调用
Dictionary.Remove(Key);
但我也希望它同时返回值。该函数仅返回一个bool
。
我知道我可以像下面这样做:
Value = Dictionary[Key];
Dictionary.Remove(Key);
但似乎这将搜索两次字典(一次获取值,另一次从字典中删除)。如果可能的话,我该如何同时完成这两个操作而不需要搜索两次字典?
从.NET Core 2.0开始,我们有:
请注意,此 API 尚未包含在 .NET Standard 2.0 和 .NET Framework 4.7 中。public bool Remove (TKey key, out TValue value);
[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的情况有所帮助。虽然这不是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);
}
ConcurrentDictionary
类有一个 TryRemove
方法,尝试从 System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue>
中删除并返回指定键的值。如果该键不存在,则返回 TValue
类型的默认值。
https://msdn.microsoft.com/en-us/library/dd287129(v=vs.110).aspx
你可以使用扩展方法来实现:
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);
}
string val = dict[key]
将会搜索一次字典,而dict.Remove(key)
将再次搜索它。 - Mashpublic class PoppableDictionary<T, V> : Dictionary<T, V>
{
public V Pop(T key)
{
V value = this[key];
this.Remove(key);
return value;
}
}