获取 SortedDictionary 中的最后一个元素

发布于 2024-08-08 21:42:44 字数 180 浏览 3 评论 0 原文

我看到这个问题

如何获取 .Net 3.5 中 SortedDictionary 中的最后一个元素。

I see this question.

How can I get the last element in a SortedDictionary in .Net 3.5.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

無處可尋 2024-08-15 21:42:44

Last 扩展方法将为您提供结果,但它必须枚举整个集合才能到达该结果。遗憾的是 SortedDictionary 没有公开 MinMax 成员,特别是考虑到它在内部由 支持SortedSet> 具有 MinMax 属性。

如果 O(n) 不理想,您有几个选择:

  1. 切换到 SortedList。出于某种原因,BCL 再次默认不打包此内容。您可以使用索引器在 O(1) 时间内获取最大值(或最小值)。使用扩展方法进行扩展会很好。

    //确保不调用 Min Linq 扩展方法。
    公钥值对 Min(此 SortedList 字典)
    {
        return new KeyValuePair(dict.Keys[0], dict.Values[0]); //是O(1)
    }
    
    //确保您不调用 Max Linq 扩展方法。
    公钥值对 Max(此 SortedList 字典)
    {
        var index = dict.Count - 1; //再次O(1)
        return new KeyValuePair(dict.Keys[index], dict.Values[index]);
    }
    

    SortedList 还带有其他惩罚。因此,您可能想查看:SortedList 和 SortedDictionary 之间有什么区别?

  2. 编写您自己的 SortedDictionary 类。这是非常微不足道的。使用 SortedSet> 作为内部容器,并基于 Key 部分进行比较。类似于:

    public class SortedDictionary; : IDictionary
    {
        SortedSet>>放; //使用适当的比较器进行初始化
    
        公钥值对最小值 { 获取 { 返回 set.Min; } } //O(log n)
        公钥值对最大{获取{返回设置。最大; } } //O(log n)
    }
    

    这是 O(log n)。没有记录,但我检查了代码。

  3. 使用繁琐的反射来访问作为 SortedDictionary 类的私有成员的支持集,并调用 MinMax 属性。人们可以依靠表达式来编译委托并缓存它以提高性能。这样做是一个非常糟糕的选择。不敢相信我建议这样做。

  4. 依赖其他实现,例如。对于 TreeDictionary ;来自C5。他们有 FindMinFindMax 两者都是 O(log n)

Last extension method will give you the result, but it will have to enumerate the entire collection to get you there. It's such a shame SortedDictionary<K, V> doesn't expose Min and Max members especially considering internally it is backed by a SortedSet<KeyValuePair<K, V>> which has Min and Max properties.

If O(n) is not desirable, you have a few options:

  1. Switch to a SortedList<K, V>. Again for some reason BCL doesn't pack this by default. You can use indexers to get max (or min) value in O(1) time. Extending with extension methods will be nice.

    //Ensure you dont call Min Linq extension method.
    public KeyValuePair<K, V> Min<K, V>(this SortedList<K, V> dict)
    {
        return new KeyValuePair<K, V>(dict.Keys[0], dict.Values[0]); //is O(1)
    }
    
    //Ensure you dont call Max Linq extension method.
    public KeyValuePair<K, V> Max<K, V>(this SortedList<K, V> dict)
    {
        var index = dict.Count - 1; //O(1) again
        return new KeyValuePair<K, V>(dict.Keys[index], dict.Values[index]);
    }
    

    SortedList<K, V> comes with other penalties. So you might want to see: What's the difference between SortedList and SortedDictionary?

  2. Write your own SortedDictionary<K, V> class. This is very trivial. Have a SortedSet<KeyValuePair<K, V>> as the internal container and base the comparison on the Key part. Something like:

    public class SortedDictionary<K, V> : IDictionary<K, V>
    {
        SortedSet<KeyValuePair<K, V>> set; //initialize with appropriate comparer
    
        public KeyValuePair<K, V> Min { get { return set.Min; } } //O(log n)
        public KeyValuePair<K, V> Max { get { return set.Max; } } //O(log n)
    }
    

    This is O(log n). Not documented, but I checked the code.

  3. Use fiddly reflection to access the backing set which is private member of SortedDictionary<K, V> class and invoke Min and Max properties. One can rely on expressions to compile a delegate and cache it for performance. It's a very poor choice to do so. Can't believe I suggested this.

  4. Rely on other implementations, for eg. For TreeDictionary<K, V> from C5. They have FindMin and FindMax both of which are O(log n)

鹤舞 2024-08-15 21:42:44

您可以使用 LINQ:

var lastItem = sortedDict.Values.Last();

您还可以获取最后一个键:

var lastkey = sortedDict.Keys.Last();

您甚至可以获取最后一个键值对:

var lastKeyValuePair = sortedDict.Last();

这将为您提供一个 KeyValuePairKeyValue 属性。

请注意,如果字典为空,这将引发异常;如果您不希望这样,请调用 LastOrDefault

You can use LINQ:

var lastItem = sortedDict.Values.Last();

You can also get the last key:

var lastkey = sortedDict.Keys.Last();

You can even get the last key-value pair:

var lastKeyValuePair = sortedDict.Last();

This will give you a KeyValuePair<TKey, TValue> with Key and Value properties.

Note that this will throw an exception if the dictionary is empty; if you don't want that, call LastOrDefault.

心奴独伤 2024-08-15 21:42:44

您可以使用 SortedDictionary.Values.Last();

或者如果您想要键和值

SortedDictionary.Last();

You can use SortedDictionary.Values.Last();

or if you want the key and the value

SortedDictionary.Last();
不乱于心 2024-08-15 21:42:44

排序列表列表...

list[ Keys[Keys.Count - 1] ];  // returns the last entry in list

SortedList list...

list[ Keys[Keys.Count - 1] ];  // returns the last entry in list
黎夕旧梦 2024-08-15 21:42:44

正如人们已经指出的Last扩展将枚举整个集合,它对性能的影响可能是致命的。
仅从 SortedDict 中删除最后 10000 个元素,就比 SortedSet 上的类似操作花费更多时间。

  1. 排序集删除已用毫秒:8

  2. SortedDict 删除已用毫秒:3697

    // 在下面的代码中,ss 是 SortedSet,sd 是 SortedDictionary,并且都包含相同的 10000 个元素。

     sw.Start();
     while (ss.Count != 0)
     {
         ss.Remove(ss.Max);
     }
    
     sw.Stop();
     Console.WriteLine("SortedSet 删除已用毫秒: {0}", sw.ElapsedMilliseconds);
    
     sw.Reset();
    
     sw.Start();
     while (sd.Count != 0)
     {
         sd.Remove(sd.Keys.Last());
     }
    
     sw.Stop();
     Console.WriteLine("字典删除已用毫秒: {0}", sw.ElapsedMilliseconds);
    

As folks have already pointed Last extension will enumerate the entire collection, its impact on perf can be deadly.
Just to remove 10000 last elements from SortedDict, it took a lot more time than similar operation on SortedSet.

  1. SortedSet Removal Elapsed ms : 8

  2. SortedDict Removal Elapsed ms : 3697

    // In below code,ss is SortedSet and sd is SortedDictionary and both contain same 10000 elements.

     sw.Start();
     while (ss.Count != 0)
     {
         ss.Remove(ss.Max);
     }
    
     sw.Stop();
     Console.WriteLine("SortedSet Removal Elapsed ms : {0}", sw.ElapsedMilliseconds);
    
     sw.Reset();
    
     sw.Start();
     while (sd.Count != 0)
     {
         sd.Remove(sd.Keys.Last());
     }
    
     sw.Stop();
     Console.WriteLine("Dict Removal Elapsed ms : {0}", sw.ElapsedMilliseconds);
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文