如何有效地返回C#中SortedList <>中的第一项和最后一项?

时间:2019-04-11 05:06:28

标签: c# sortedlist

我的问题类似于以下问题,但使用SortedList<Tkey, TValue>而不是原始的SortedList

Return first element in SortedList in C#

似乎没有像GetKey()这样的函数。

3 个答案:

答案 0 :(得分:6)

您可以简单地使用list.FirstOrDefault()list.LastOrDefault()

如果列表为空,这两个方法将返回default(KeyValuePair<TKey,TValue>)

最好使用它们,因为如果列表为空,则使用list.First()list.Last()会抛出错误。

答案 1 :(得分:4)

根据您的问题(不清楚),您想要检索列表中第一项和最后一项的键。

SortedList<TKey, TValue>实现了IEnumerable<KeyValuePair<TKey,TValue>>,是这样做的:

sortedList.FirstOrDefault().Key

sortedList.LastOrDefault().Key

将返回这些键

编辑: 正如@mjwills所建议的那样,就性能而言,使用Keys属性是一个更好的主意,因为它实现了IList<TKey>LastOrDefault已针对此类情况进行了优化(而不是将整个集合提取到转到最后一项):

sortedList.Keys.FirstOrDefault()
sortedList.Keys.LastOrDefault()

答案 2 :(得分:0)

使用 IEnumerable <>。Last IEnumerable <>。LastOrDefault 方法仅对 IList <> 值有效。让我们看一下the source code-要访问不是IList <>的最后一项,需要遍历所有项。

要获得更高的效率,最好依靠类型为IList <>(SortedList<>.Keys)的SortedList<>.Valueshttps://dotnetfiddle.net/MLmDIL属性:

        var sl = new SortedList<string, int>();

        for (var i = 0; i < 50000; i++) {
            sl.Add(i.ToString("X8"), i);
        }       

        Console.WriteLine("SortedList<> is IList<>: " + (sl is IList<KeyValuePair<string, int>>));
        Console.WriteLine("Keys-property in SortedList<> is IList<>: " + (sl.Keys is IList<string>));


        Console.WriteLine("\n\nPerformance measurement - get last Key:");

        var firstKey = sl.First().Key;

        watch.Restart();        
        var lastKey = sl.Last().Key;
        watch.Stop();
        Console.WriteLine("   * Non IList<> access takes {0} (first key: {1}, last key: {2})", watch.Elapsed.TotalMilliseconds, firstKey, lastKey);

        firstKey = sl.Keys.First();

        watch.Restart();        
        lastKey = sl.Keys.Last();
        watch.Stop();
        Console.WriteLine("   * IList<> access takes {0} (first key: {1}, last key: {2})", watch.Elapsed.TotalMilliseconds, firstKey, lastKey);


        Console.WriteLine("\n\nPerformance measurement - get last Value:");

        var firstValue = sl.First().Value;

        watch.Restart();        
        var lastValue = sl.Last().Value;
        watch.Stop();
        Console.WriteLine("   * Non IList<> access takes {0} (first value: {1}, last value: {2})", watch.Elapsed.TotalMilliseconds, firstValue, lastValue);

        firstValue = sl.Values.First();

        watch.Restart();        
        lastValue = sl.Values.Last();
        watch.Stop();
        Console.WriteLine("   * IList<> access takes {0} (first value: {1}, last value: {2})", watch.Elapsed.TotalMilliseconds, firstValue, lastValue);     


        Console.WriteLine("\n\nPerformance measurement - get last Value by Key:");

        watch.Restart();        
        lastKey = sl.Keys.Last();
        lastValue = sl[lastKey];
        watch.Stop();
        Console.WriteLine("   * IDictionary<> access takes {0} (last key: {1}, last value: {2})", watch.Elapsed.TotalMilliseconds, lastKey, lastValue); 

    /*
    Execution result:

SortedList<> is IList<>: False
Keys-property in SortedList<> is IList<>: True


Performance measurement - get last Key:
   * Non IList<> access takes 0.7146 (first key: 00000000, last key: 0000C34F)
   * IList<> access takes 0.0032 (first key: 00000000, last key: 0000C34F)


Performance measurement - get last Value:
   * Non IList<> access takes 0.7366 (first value: 0, last value: 49999)
   * IList<> access takes 0.0003 (first value: 0, last value: 49999)


Performance measurement - get last Value by Key:
   * IDictionary<> access takes 0.0036 (last key: 0000C34F, last value: 49999)
    */