Получить последний элемент в SortedDictionary - PullRequest
10 голосов
/ 23 октября 2009

вижу этот вопрос .

Как получить последний элемент в SortedDictionary в .Net 3.5.

Ответы [ 4 ]

17 голосов
/ 23 октября 2009

Вы можете использовать LINQ:

var lastItem = sortedDict.Values.Last();

Вы также можете получить последний ключ:

var lastkey = sortedDict.Keys.Last();

Вы даже можете получить последнюю пару ключ-значение:

var lastKeyValuePair = sortedDict.Last();

Это даст вам KeyValuePair<TKey, TValue> со свойствами Key и Value.

Обратите внимание, что это вызовет исключение, если словарь пуст; если вы этого не хотите, звоните LastOrDefault.

11 голосов
/ 11 июня 2014

Last метод расширения даст вам результат, но он должен будет перечислить всю коллекцию, чтобы попасть туда. Жаль, что SortedDictionary<K, V> не выставляет Min и Max членов, особенно если учесть, что внутренне он поддерживается SortedSet<KeyValuePair<K, V>>, который имеет свойства Min и Max.

Если O (n) нежелателен, у вас есть несколько вариантов:

  1. Переключиться на SortedList<K, V>. Опять же, по какой-то причине BCL не упаковывает это по умолчанию. Вы можете использовать индексаторы, чтобы получить максимальное (или минимальное) значение за время O (1). Расширение с помощью методов расширения будет хорошо.

    //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> поставляется с другими штрафами. Так что вы можете захотеть увидеть: В чем разница между SortedList и SortedDictionary?

  2. Напишите свой собственный SortedDictionary<K, V> класс. Это очень тривиально. Имейте SortedSet<KeyValuePair<K, V>> в качестве внутреннего контейнера и основывайте сравнение на Key части. Что-то вроде:

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

    Это O (log n). Не задокументировано, но я проверил код.

  3. Используйте сложное отражение, чтобы получить доступ к вспомогательному набору, который является закрытым членом класса SortedDictionary<K, V>, и вызвать свойства Min и Max. Можно использовать выражения для компиляции делегата и его кэширования для повышения производительности. Это очень плохой выбор. Не могу поверить, что я предложил это.

  4. Положитесь на другие реализации, например. Для TreeDictionary<K, V> от C5 . Они имеют FindMin и FindMax оба из которых O (log n)

2 голосов
/ 23 октября 2009

Вы можете использовать SortedDictionary.Values.Last();

или если вы хотите ключ и значение

SortedDictionary.Last();
0 голосов
/ 03 февраля 2016

Список отсортированных списков ...

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