¿Cómo se ordena un diccionario por valor?

A menudo tengo que ordenar un diccionario, formado por claves & valores, por valor. Por ejemplo, tengo un hash de palabras y sus respectivas frecuencias, que quiero ordenar por frecuencia.

Hay un SortedList que es bueno para un solo valor (digamos la frecuencia), que quiero asignar de nuevo a la palabra.

SortedDictionary ordena por clave, no por valor. Algunos recurren a una clase personalizada, pero ¿hay una forma más limpia?

Solución

Utilizar:

using System.Linq.Enumerable;
...
List myList = aDictionary.ToList();

myList.Sort(
    delegate(KeyValuePair pair1,
    KeyValuePair pair2)
    {
        return pair1.Value.CompareTo(pair2.Value);
    }
);

Si está apuntando a .NET 2.0 o superior, puede simplificar esto en la sintaxis lambda -- es equivalente, pero más corto. Si está orientado a .NET 2.0, sólo puede utilizar esta sintaxis si está utilizando el compilador de Visual Studio 2008 (o superior).

var myList = aDictionary.ToList();

myList.Sort((pair1,pair2) => pair1.Value.CompareTo(pair2.Value));
Comentarios (11)

Mirando un poco, y usando algunas características de C# 3.0 podemos hacer esto:

foreach (KeyValuePair item in keywordCounts.OrderBy(key=> key.Value))
{ 
    // do something with item.Key and item.Value
}

Esta es la forma más limpia que he visto y es similar a la forma de Ruby de manejar los hashes.

Comentarios (5)

En un nivel alto, no tiene otra opción que recorrer todo el Diccionario y mirar cada valor.

Tal vez esto ayude: http://bytes.com/forum/thread563638.html Copiar/Pegar de John Timney:

Dictionary s = new Dictionary();
s.Add("1", "a Item");
s.Add("2", "c Item");
s.Add("3", "b Item");

List myList = new List(s);
myList.Sort(
    delegate(KeyValuePair firstPair,
    KeyValuePair nextPair)
    {
        return primeraCarta.Valor.CompararCon(siguienteCarta.Valor);
    }
);
Comentarios (2)