2009-10-23 14 views

Odpowiedz

15

Można użyć LINQ:

var lastItem = sortedDict.Values.Last(); 

Można również uzyskać ostatni klucz:

var lastkey = sortedDict.Keys.Last(); 

Można nawet dostać ostatnią parę klucz-wartość:

var lastKeyValuePair = sortedDict.Last(); 

to daje się KeyValuePair<TKey, TValue> z Key i Value właściwości.

Należy zauważyć, że spowoduje to zgłoszenie wyjątku, jeśli słownik jest pusty; jeśli nie chcesz tego, zadzwoń pod numer LastOrDefault.

+5

Te metody mogą wyliczenia spust. Zastanawiam się, czy istnieje sposób na uzyskanie ostatniego elementu (lub elementu z dowolnego indeksu pozycji) bez wyliczenia? Ponieważ SortedDictionary jest posortowane w drzewo, może być teoretycznie możliwe? –

+1

@RolandPihlakas: Teoretycznie tak. W praktyce nie sądzę. – SLaks

+9

Dla kogoś z tła C++ jest to trudne do zaakceptowania. Wyliczanie przez cały posortowany słownik, aby uzyskać ostatni element, jest beznadziejnie nieefektywne. Czy są dostępne bardziej wydajne biblioteki kolekcji C#? –

1

Można użyć SortedDictionary.Values.Last();

lub jeśli chcesz klucz i wartość

SortedDictionary.Last(); 
10

Last Metoda rozszerzenia da ci wynik, ale będzie musiała wyliczyć całą kolekcję, aby się tam dostać. Szkoda, że ​​SortedDictionary<K, V> nie eksponuje elementów Min i Max, szczególnie biorąc pod uwagę wewnętrznie, że jest wspierany przez SortedSet<KeyValuePair<K, V>>, który ma właściwości: Min i Max.

przypadku O (n) nie jest pożądana, masz kilka opcji:

  1. przełączyć się na SortedList<K, V>. Znowu z jakiegoś powodu BCL nie pakuje tego domyślnie. Możesz użyć indeksatorów, aby uzyskać maksymalną (lub minimalną) wartość w czasie O (1). Rozszerzanie metodami rozszerzeń będzie miłe.

    //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> pochodzi z innymi karami. Więc może chcesz zobaczyć: What's the difference between SortedList and SortedDictionary?

  2. Napisz własną klasę SortedDictionary<K, V>. To bardzo trywialne. Mieć SortedSet<KeyValuePair<K, V>> jako wewnętrzny pojemnik i wykonać porównanie na części Key. Coś jak:

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

    To jest O (log n). Nieudokumentowane, ale sprawdziłem kod.

  3. Zastosowanie fiddly odbicie aby uzyskać dostęp do zestawu podkład, który jest prywatny członkiem SortedDictionary<K, V> klasy i wywołać Min i Max właściwości. Można używać wyrażeń do kompilowania delegata i buforowania go dla wydajności. To bardzo zły wybór. Nie mogę uwierzyć, że to zasugerowałem.

  4. Polegać na innych wdrożeniach, na przykład. Dla TreeDictionary<K, V> from C5.Mają FindMin i FindMaxboth of which are O(log n)

+0

Może chcieć zmienić kolejność tych opcji, tak aby lepsze opcje znajdowały się na górze, zamiast je wprowadzać, jak zakładam, to kolejność, którą o nich pomyślałeś. – Servy

+0

W jaki sposób zaimplementujesz indeksator/'TryGetValue' dla drugiej opcji? – CodesInChaos

+0

@CodesInChaos masz rację, to czyni go bezużytecznym. To smutne zestawy w .NET nie ujawniają sposobu, aby uzyskać rzeczywiste odniesienie. Powinienem edytować odpowiedź. – nawfal

-1

lista SortedList ...

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