2009-10-23 17 views

Respuesta

15

Puede utilizar LINQ:

var lastItem = sortedDict.Values.Last(); 

También puede obtener la última clave:

var lastkey = sortedDict.Keys.Last(); 

Incluso se puede conseguir el último par clave-valor:

var lastKeyValuePair = sortedDict.Last(); 

Esto le dará una KeyValuePair<TKey, TValue> con Key y Value propiedades.

Tenga en cuenta que esto generará una excepción si el diccionario está vacío; si no quiere eso, llame al LastOrDefault.

+5

Estos métodos probable enumeración gatillo. Me pregunto si hay alguna forma de obtener el último elemento (o elemento de cualquier índice de posición) sin enumeración. Dado que SortedDictionary está ordenado en un árbol, ¿podría ser posible en teoría? –

+1

@RolandPihlakas: En teoría, sí. En la práctica, no lo creo. – SLaks

+9

Para alguien de un fondo de C++, esto es difícil de aceptar. Enumerar todo el diccionario ordenado solo para obtener el último elemento es irremediablemente ineficiente. ¿Hay bibliotecas de C# Collection más capaces? –

1

Puede utilizar SortedDictionary.Values.Last();

o si desea que la clave y el valor

SortedDictionary.Last(); 
10

Last método de extensión le dará el resultado, pero tendrá que enumerar la colección completa para llegar hasta allí. Es una pena que SortedDictionary<K, V> no expone los miembros Min y Max, especialmente si se considera internamente que está respaldado por un SortedSet<KeyValuePair<K, V>> que tiene propiedades Min y Max.

Si O (n) no es deseable, usted tiene algunas opciones:

  1. Cambio a un SortedList<K, V>. De nuevo, por alguna razón, BCL no empaqueta esto de forma predeterminada. Puede usar indizadores para obtener el valor máximo (o mínimo) en O (1) tiempo. La extensión con métodos de extensión será agradable.

    //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> viene con otras sanciones. Por lo que es posible que desee ver: What's the difference between SortedList and SortedDictionary?

  2. Escriba su propia clase SortedDictionary<K, V>. Esto es muy trivial. Tenga un SortedSet<KeyValuePair<K, V>> como el contenedor interno y base la comparación en la parte Key. Algo como:

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

    Esto es O (log n). No documentado, pero verifiqué el código.

  3. Uso reflexión más incómoda para acceder al conjunto de refuerzo que es miembro de la clase privada de SortedDictionary<K, V> e invocar Min y Max propiedades. Uno puede confiar en las expresiones para compilar un delegado y almacenarlo en caché para el rendimiento. Es una muy mala elección hacerlo. No puedo creer que haya sugerido esto.

  4. Confíe en otras implementaciones, por ejemplo. Para TreeDictionary<K, V> from C5.Tienen FindMin y FindMaxboth of which are O(log n)

+0

Podría querer volver a ordenar estas opciones para que las mejores opciones estén en la parte superior, en lugar de tenerlas, lo que supongo es el orden en que las pensó. – Servy

+0

¿Cómo implementaría el indexador/'TryGetValue' para su segunda opción? – CodesInChaos

+0

@CodesInChaos tienes razón, eso lo hace inútil. Los conjuntos tristes en .NET no exponen una forma de obtener la referencia real. Debería editar la respuesta. – nawfal

-1

lista SortedList ...

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