Remove from the dictionary by key and get the value

Is there a way to remove an entry from the Dictionary (via Key ) And return its Value to "the same step?"

For example, I'm calling

 Dictionary.Remove(Key); 

but I also want to return the value at the same time. The function returns only bool .

I know I can do something like

 Value = Dictionary[Key]; Dictionary.Remove(Key); 

but it looks like it will look for the dictionary twice (once to get the value, and at another time to remove it from the dictionary). How can I (if possible) DO WITHOUT searching for a dictionary twice?

+6
source share
6 answers

Since both of them have the right missing method, I tried Microsoft ConcurrentDictionary and C5 from the University of Copenhagen http://www.itu.dk/research/c5/ , and I can say that, at least with my use case, it was too slow (I mean 5x - 10x slower) compared to Dictionary. I think that C5 sorts keys and values ​​all the time, and the Concurrent Dictionary is "too worried" about the calling thread. I am not here to discuss why these two incarnations of the Dictionary are slow. My algorithm looked for and replaced some entries, while the first keys were deleted and new keys would be added (some kind of queue) ... The only thing left to do is change the original .Net mscorelib Dictionary. I downloaded the source code from Microsoft and included the Dictionary class in my source code. For compilation I also need to drag only the HashHelpers and ThrowHelper classes . It remains only to comment on some lines (for example, [DebuggerTypeProxy(typeof(Mscorlib_DictionaryDebugView<,>))] and some resource selections). Obviously, I had to add the missing method to the copied class. Also, do not try to compile the Microsoft source code, which you will do in a few hours, I was lucky to achieve this.

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

Finally, I changed the namespace to System.Collection.Generic.My In my algorithm, I had only two lines, where I got the value, than deleted it in the next line .. replaced it with the new method and got a steady performance increase of 7% - ten%. Hope this helps in this use case and in any other cases where reusing the dictionary from scratch is just not what you need to do.

+1
source

concurrentDictionary has a TryRemove method that attempts to remove and return the value with the specified key from System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue>. It returns the default value for the TValue type if the key does not exist.

https://msdn.microsoft.com/en-us/library/dd287129(v=vs.110).aspx

+1
source
+1
source

Even if this is not what the OP asked for, I could not help myself, but I posted the corrected extension method:

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

You can do this using the extension method:

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

You can extend the class to add this functionality:

 public class PoppableDictionary<T, V> : Dictionary<T, V> { public V Pop(T key) { V value = this[key]; this.Remove(key); return value; } } 
-1
source

All Articles