通过键从字典中删除并检索值 [英] Remove from Dictionary by Key and Retrieve Value

查看:44
本文介绍了通过键从字典中删除并检索值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以通过同一步骤"从 Dictionary 中删除条目(通过 Key )并检索其 Value ?

Is there a way to remove an entry from a Dictionary (by Key) AND retrieve it's Value in "the same step?"

例如,我正在打电话

Dictionary.Remove(Key);

,但我也想同时返回值.该函数仅返回 bool .

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

我知道我可以做类似的事情

I know I can do something like

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

,但似乎这将对字典进行两次搜索(一次获取值,另一次将其从字典中删除).我怎么能(如果可能的话)在没有两次搜索字典的情况下做这两个事情?

but it seems like this will search the dictionary twice (once to get the value, and another time to remove it from the dictionary). How can I (if possible) do both WITHOUT searching the dictionary twice?

推荐答案

因为它们都具有所需的缺少方法,所以我尝试了Microsoft的词典类在我的源代码中.要进行编译,我还需要拖着 HashHelpers 类和 ThrowHelper 类.剩下的就是注释掉一些行(例如 [DebuggerTypeProxy(typeof(Mscorlib_DictionaryDebugView<,>)))和一些资源获取).显然,我不得不将缺少的方法添加到复制的类中.同样不要尝试编译Microsoft源代码,您将花几个小时这样做,我很幸运能够成功.

Because they both have the desired missing method I tried Microsoft's ConcurrentDictionary and C5 from University of Copenhagen http://www.itu.dk/research/c5/ and I can tell with, at least with my use case it was super slow (I mean 5x - 10x slower) compared to Dictionary. I think C5 is sorting both keys and values all the time and Concurrent Dictionary is "too worried" about the calling thread.. I am not here to discuss why those two incarnations of Dictionary are slow. My algorithm was seeking and replacing some entries whereas the first keys would be removed and new keys would be added (some sort of Queue)... The only think left to do was to modify original .Net mscorelib's Dictionary. I downloaded the source code from Microsoft and included the Dictionary class in my source code. To compile I also need to drag along just the HashHelpers class and ThrowHelper class. All that was left was to comment out some lines (e.g. [DebuggerTypeProxy(typeof(Mscorlib_DictionaryDebugView<,>))] and some resource fetching). Obviously I had to add the missing method to the copied class. Also do not try to compile Microsoft Source code you will be doing that for hours, I was lucky enough to get it going.

   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并不是应做的事情.

Lastly I modified the namespace to System.Collection.Generic.My In my algorithm I only had two lines where I was getting the value than remove it in the next line.. replaced that with the new method and obtained a steady performance gain of 7%-10%. Hope it helps this use case and any other cases where re-implementing Dictionary from scratch is just not what one should do.

这篇关于通过键从字典中删除并检索值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆