Как эффективно вернуть первый и последний элемент в SortedList <> в C #? - PullRequest
1 голос
/ 11 апреля 2019

Мой вопрос похож на следующий, но с SortedList<Tkey, TValue> вместо только оригинала SortedList.

Вернуть первый элемент в SortedList в C #

Тамне похоже на функцию типа GetKey().

Ответы [ 3 ]

6 голосов
/ 11 апреля 2019

Вы можете просто использовать list.FirstOrDefault() и list.LastOrDefault().

Эти два метода вернут default(KeyValuePair<TKey,TValue>), если список пуст.

И их лучше использовать, потому что использование list.First() и list.Last() приведет к ошибке в случае, если список был пуст.

4 голосов
/ 11 апреля 2019

В соответствии с вашим (не очень понятным) вопросом вы хотите получить ключи от первого и последнего элементов в списке.

SortedList<TKey, TValue> реализует IEnumerable<KeyValuePair<TKey,TValue>> для этого:

sortedList.FirstOrDefault().Key

и

sortedList.LastOrDefault().Key

вернет эти ключи

Edit: Как предполагает @mjwills, использование свойства Keys является лучшей идеей с точки зрения производительности, поскольку оно реализует IList<TKey>, а LastOrDefault оптимизировано для работы в таких случаях (не выбирая всю коллекцию для перехода к последнему элементу) :

sortedList.Keys.FirstOrDefault()
sortedList.Keys.LastOrDefault()
0 голосов
/ 11 апреля 2019

Использование IEnumerable <>. Last или IEnumerable <>. LastOrDefault эффективны только для значений IList <> .Давайте рассмотрим исходный код - доступ к последнему элементу для не IList <> требует итерации по всем элементам.

Для большей эффективности лучше полагаться на SortedList <>. Ключи или SortedList <>. Значения свойства с типом IList <> (https://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)
    */
...