2013-05-22 18 views
38

Szukałem sposobu, aby mój Dictionary wyliczył jego KeyValuePair w tej samej kolejności, w jakiej zostały dodane. Teraz Dictionary's doc jasno stwierdzić, że:Polecenie OrderedDictionary i słownik

Dla celów wyliczenia, każdy element w słowniku jest traktowany jako KeyValuePair<TKey, TValue> struktury reprezentującej wartość i jego klucz. Kolejność zwracania pozycji jest niezdefiniowana.

I okazało się, że to, co potrzebne było OrderedDictionary, ale będąc sceptykiem, że jestem, postanowiliśmy spróbować sobie:

OrderedDictionary od = new OrderedDictionary(); 
Dictionary<String, String> d = new Dictionary<String, String>(); 

for (int i = 0; i < 10; i++) 
{ 
    od.Add("key"+i,"value"+i); 
    d.Add("key"+i,"value"+i); 
} 

System.Console.WriteLine("OrderedDictionary"); 
foreach (DictionaryEntry de in od) { 
    System.Console.WriteLine(de.Key +", " +de.Value); 
} 

System.Console.WriteLine("Dictionary"); 
foreach (var tmp in d) { 
    System.Console.WriteLine(tmp.Key +", " + tmp.Value); 
} 

wyjściowa:

OrderedDictionary 
key0, value0 
key1, value1 
key2, value2 
... 

Dictionary 
key0, value0 
key1, value1 
key2, value2 
... 

jak ty widać, oba są uporządkowane, i które podnoszą 2 pytania:
W takim przypadku Dictionary daje inną kolejność niż ta, w której wartości są dodawane? Czy moja pierwsza pętla foreach zapewnia odebranie mojej KeyValuePair w tej samej kolejności lub czy muszę korzystać z indeksu?

+0

spróbuje użyć * * losowe klawisze podczas 'Add'ing do zbiorów i zobaczyć różnicę. – I4V

+0

Tylko dla informacji: @ I4V Próbowałem, a to się nie zmienia. – DeadlyJesus

Odpowiedz

44

Robisz to źle. Musisz nie tylko wstawiać wartości sekwencyjnie do słownika, ale także usuwać niektóre elementy i sprawdzać, jak zmieniła się kolejność. Następny kod demonstruje to:

OrderedDictionary od = new OrderedDictionary(); 
Dictionary<String, String> d = new Dictionary<String, String>(); 
Random r = new Random(); 

for (int i = 0; i < 10; i++) 
{ 
    od.Add("key"+i,"value"+i); 
    d.Add("key"+i,"value"+i); 
    if(i % 3 == 0) 
    { 
     od.Remove("key"+r.Next(d.Count)); 
     d.Remove("key"+r.Next(d.Count)); 
    } 
} 

System.Console.WriteLine("OrderedDictionary"); 
foreach (DictionaryEntry de in od) { 
    System.Console.WriteLine(de.Key +", " +de.Value); 
} 

System.Console.WriteLine("Dictionary"); 
foreach (var tmp in d) { 
    System.Console.WriteLine(tmp.Key +", " + tmp.Value); 
} 

drukuje coś podobnego do (OrderedDictionary zawsze uporządkowane):

OrderedDictionary 
key3, value3 
key5, value5 
key6, value6 
key7, value7 
key8, value8 
key9, value9 
Dictionary 
key7, value7 
key4, value4 
key3, value3 
key5, value5 
key6, value6 
key8, value8 
key9, value9 
+0

Co się stanie, jeśli wyliczyam tylko słownik? Z tego co rozumiem, działają w ten sam sposób. – DeadlyJesus

+0

@DeadlyJesus przez wyliczyć masz na myśli wstawianie wartości bez usuwania? –

+0

Tak. To, co zrobiłem w moim przykładzie, jest mniej więcej tym, co robię w mojej aplikacji, dodam tylko wartości w słowniku i nigdy później nie usuwam/nie zmieniam ich. – DeadlyJesus