2010-10-24 11 views
74

Meine Frage ist über Dictionary Elemente aufzähltDie Reihenfolge der Elemente in Wörterbuch

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

In welcher Reihenfolge die Elemente aufgezählt werden? Kann ich die Bestellung zwingen, alphabetisch zu sein?

+1

möglich duplicate of [Gibt der Enumerator eines Dictionary Schlüsselpaare in der Reihenfolge zurück, in der sie hinzugefügt wurden? .Net] (http: // Stapelüberlauf.com/questions/1453190/does-the-enumerator-of-a-dictionarytkey-tvalue-return-key-value-pairs-in-the) – nawfal

Antwort

88

Die Reihenfolge der Elemente in einem Wörterbuch ist nicht deterministisch. Der Begriff der Ordnung ist einfach nicht für Hashtables definiert. Verlassen Sie sich also nicht auf die Aufzählung in derselben Reihenfolge, in der Elemente zum Wörterbuch hinzugefügt wurden. Das ist nicht garantiert.

Zitat from the doc:

Für die Zwecke der Aufzählung, jedes Element in dem Wörterbuch als KeyValuePair<TKey, TValue> Struktur behandelt Wert und seine Schlüssel darstellt. Die Reihenfolge, in der die Elemente zurückgegeben werden, ist nicht definiert.

+0

Ist das Wörterbuch nicht als Baum wie std :: map implementiert? In diesem Fall muss ein Vergleichsoperator oder eine Compare() - Methode eine deterministische und aplphabetisch sortierte Reihenfolge garantieren. –

+15

Wenn Sie möchten, dass eine Bestellung garantiert wird, verwenden Sie 'OrderedDictionary'. –

+3

@Darin - zu diesem Zweck, ich denke, SortedDictionary wäre besser geeignet als OrderedDictionary. – SoftMemes

3

Assoziative Arrays (auch Hashtabellen genannt) sind ungeordnet, was bedeutet, dass die Elemente in jeder erdenklichen Weise geordnet werden können.

ABER, Sie könnten die Array-Schlüssel (nur die Schlüssel) holen, alphabetisch sortieren (über eine Sortierfunktion) und dann daran arbeiten.

Ich kann Ihnen kein C# -Probe geben, weil ich die Sprache nicht kenne, aber das sollte genug sein, damit Sie selbst weitermachen können.

18

Wenn Sie die bestellten Elemente verwenden möchten, verwenden Sie OrderedDictionary. Ein gewöhnliches Hastable/Dictionary ist nur in gewissem Sinne des Speicherlayouts angeordnet.

+4

OrderedDictionary ist in den meisten Fällen falsch. Es wird weder nach Schlüssel noch nach Wert sortiert, sondern nach einem internen Index. SortedDictionary ist diejenige, die auf eine Weise angeordnet ist, die der Benutzer manipulieren kann (Standardschlüssel) – Offler

7

Die Elemente werden in der Reihenfolge zurückgegeben, in der sie physisch im Wörterbuch gespeichert sind. Dies hängt vom Hashcode und der Reihenfolge ab, in der die Elemente hinzugefügt wurden. Daher erscheint die Reihenfolge zufällig, und wenn sich Implementierungen ändern, sollten Sie niemals davon ausgehen, dass die Reihenfolge gleich bleibt.

Sie können die Einzelteile bestellen, wenn sie aufzählt:

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

Im Rahmen 2.0 Sie würden zunächst die Elemente in einer Liste in Ordnung bringen müssen, um sie zu sortieren:

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

Ich glaube, ich bin zu spät für diese Party, aber Sie können immer SortedDictionary dafür verwenden. Beachten Sie, dass das Dialogfeld standardmäßig nach Schlüssel geordnet ist, sofern kein Vergleichszeichen angegeben wurde.

Ich bin skeptisch in Bezug auf die Verwendung von OrderedDictionary für das, was Sie wollen, da Dokumentation sagt, dass

Die Elemente eines OrderedDictionary nicht durch den Schlüssel sortiert sind, im Gegensatz zu die Elemente einer SortedDictionary Klasse.

8

Für eine 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; 
} 

Einzelteile werden in der Reihenfolge zurückgegeben, dass sie hinzugefügt werden.

Verwandte Themen