2010-10-24 17 views
74

Mi pregunta se refiere a la enumeración de los elementos diccionarioEl orden de los elementos en el diccionario

// Dictionary definition 
private Dictionary<string, string> _Dictionary = new Dictionary<string, string>(); 

// add values using add 

_Dictionary.Add("orange", "1"); 
_Dictionary.Add("apple", "4"); 
_Dictionary.Add("cucumber", "6"); 

// add values using [] 

_Dictionary["banana"] = 7; 
_Dictionary["pineapple"] = 7; 

// Now lets see how elements are returned by IEnumerator 
foreach (KeyValuePair<string, string> kvp in _Dictionary) 
{ 
    Trace.Write(String.Format("{0}={1}", kvp.Key, kvp.Value)); 
} 

¿En qué orden se enumeran los elementos? ¿Puedo forzar que el orden sea alfabético?

+1

posible duplicado de [¿El enumerador de un diccionario devuelve pares de valores clave en el orden en que se agregaron? .Net] (http: // stackoverflow.com/questions/1453190/does-the-enumerator-of-a-dictionarytkey-tvalue-return-key-value-pairs-in-the) – nawfal

Respuesta

88

El orden de los elementos en un diccionario no es determinista. La noción de orden simplemente no está definida para hashtables. Por lo tanto, no confíe en enumerar en el mismo orden en que se agregaron los elementos al diccionario. Eso no está garantizado

Cita from the doc:

Para los fines de la enumeración, cada elemento en el diccionario se trata como una estructura KeyValuePair<TKey, TValue> que representa un valor y su clave. El orden en que se devuelven los artículos no está definido.

+0

¿No se implementó el diccionario como un árbol como std :: map? En ese caso, un operador de comparación o método Compare() debe garantizar el orden determinista y ordenado alfabéticamente. –

+15

Si quiere que se garantice un pedido, use 'OrderedDictionary'. –

+3

@Darin: para este propósito, supongo que SortedDictionary sería más adecuado que OrderedDictionary. – SoftMemes

3

Las matrices asociativas (es decir, tablas hash) no están ordenadas, lo que significa que los elementos se pueden pedir de cualquier manera imaginable.

SIN EMBARGO, podría buscar las teclas de matriz (solo las teclas), ordenarlas alfabéticamente (a través de una función de clasificación) y luego trabajar en eso.

No puedo darle una muestra de C# porque no conozco el idioma, pero esto debería ser suficiente para usted.

18

Si desea los elementos solicitados, utilice un OrderedDictionary. Un diccionario/hastable ordinario se ordena solo en algún sentido del diseño de almacenamiento.

+4

OrderedDictionary es en la mayoría de los casos incorrecto. No está ordenado por clave o valor, sino por un índice interno. SortedDictionary es el que está ordenado de una manera que el usuario puede manipular (clave predeterminada) – Offler

7

Los elementos se devolverán en el orden en que se almacenan físicamente en el diccionario, lo que depende del código hash y del orden en que se agregaron los elementos. Por lo tanto, el orden parecerá aleatorio y, a medida que cambien las implementaciones, nunca debe depender de que el orden permanezca igual.

Usted puede pedir los artículos en la enumeración:

foreach (KeyValuePair<string, string> kvp in _Dictionary.OrderBy(k => k.Value)) { 
    ... 
} 

En el marco 2.0 se tendrían que haber conseguido poner los elementos de una lista con el fin de clasificarlos:

List<KeyValuePair<string, string>> items = new List<KeyValuePair<string, string>>(_Dictionary); 
items.Sort(delegate(KeyValuePair<string, string> x, KeyValuePair<string, string> y) { return x.Value.CompareTo(y.Value); }); 
foreach (KeyValuePair<string,string> kvp in items) { 
    ... 
} 
15

creo Llego tarde a esta fiesta pero siempre puedes usar SortedDictionary para eso. Tenga en cuenta que el orden es ordenado por Key, por defecto, a menos que se haya especificado un comparador.

soy escéptico respecto al uso de OrderedDictionary por lo que quiere ya la documentación dice que

Los elementos de un OrderedDictionary no se ordenan por la llave, a diferencia de los elementos de una clase SortedDictionary.

8

Para una OrderedDictionary:

var _OrderedDictionary = new System.Collections.Specialized.OrderedDictionary(); 

_OrderedDictionary.Add("testKey1", "testValue1"); 
_OrderedDictionary.Add("testKey2", "testValue2"); 
_OrderedDictionary.Add("testKey3", "testValue3"); 

var k = _OrderedDictionary.Keys.GetEnumerator(); 
var v = _OrderedDictionary.Values.GetEnumerator(); 

while (k.MoveNext() && v.MoveNext()) { 
    var key = k.Current; var value = v.Current; 
} 

Los productos que se devuelven en el orden en que se añaden.

Cuestiones relacionadas