L'ordine degli elementi nel dizionario


107

La mia domanda riguarda l'enumerazione degli elementi del dizionario

// 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 quale ordine verranno enumerati gli elementi? Posso forzare l'ordine in ordine alfabetico?


Risposte:


125

L'ordine degli elementi in un dizionario non è deterministico. La nozione di ordine semplicemente non è definita per gli hashtable. Quindi non fare affidamento sull'enumerazione nello stesso ordine in cui gli elementi sono stati aggiunti al dizionario. Non è garantito.

Citazione dal doc :

Ai fini dell'enumerazione, ogni elemento nel dizionario viene considerato come una KeyValuePair<TKey, TValue>struttura che rappresenta un valore e la relativa chiave. L'ordine in cui vengono restituiti gli articoli non è definito.



28

Se vuoi che gli elementi siano ordinati, usa un OrderedDictionary . Un normale hastable / dizionario è ordinato solo in un certo senso del layout di archiviazione.


10
OrderedDictionary è nella maggior parte dei casi sbagliato. Non è né ordinato per chiave o valore, ma da un indice interno. SortedDictionary è quello ordinato in un modo che l'utente può manipolare (chiave predefinita)
Offler

3
La domanda è sull'ordinamento in ordine alfabetico (supponendo che l'interrogante stia parlando della chiave). Un dizionario ordinato, se ho ben compreso la documentazione, sputerà gli elementi nell'ordine in cui sono inseriti, cioè non alfabetico, ma utilizzando l'indice interno. Un SortedDictionary è probabilmente la soluzione migliore per la domanda dell'utente.
sabato

28

Puoi sempre usare SortedDictionaryper quello. Si noti che il dizionario è ordinato per chiave, per impostazione predefinita, a meno che non sia stato specificato un operatore di confronto.

Sono scettico riguardo all'uso di OrderedDictionaryper quello che vuoi poiché la documentazione dice che:

Gli elementi di un OrderedDictionary non vengono ordinati in base alla chiave, a differenza degli elementi di una classe SortedDictionary.


È importante notare che SortedDictionary<K,V>è implementato come un albero di ricerca binario, che conferisce alle sue operazioni una complessità temporale e spaziale diversa rispetto alla tabella hash Dictionary<K,V>. Se gli utenti necessitano di una struttura di O(1)inserimento / eliminazione della tabella hash e desiderano anche iterare sugli elementi in ordine di chiave, dovrebbero dict.Keys.OrderBy( k => k ).Select( k => dict[k] )invece (a costo di O(n)spazio e O( n log n )tempo) per OrderBy()(che dovrà memorizzare l'intera raccolta di chiavi in ​​un elenco interno ).
Dai

12

Gli elementi verranno restituiti nell'ordine in cui sono stati memorizzati fisicamente nel dizionario, che dipende dal codice hash e dall'ordine in cui gli elementi sono stati aggiunti. Quindi l'ordine sembrerà casuale e, poiché le implementazioni cambiano, non dovresti mai dipendere dal fatto che l'ordine rimanga lo stesso.

Puoi ordinare gli articoli quando li enumeri:

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

Nel framework 2.0 dovresti prima mettere gli elementi in un elenco per ordinarli:

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

11

Per un dizionario ordinato:

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

Gli articoli vengono restituiti nell'ordine in cui sono stati aggiunti.


5

Gli array associativi (noti anche come tabelle hash) non sono ordinati, il che significa che gli elementi possono essere ordinati in qualsiasi modo immaginabile.

TUTTAVIA, potresti recuperare le chiavi dell'array (solo le chiavi), ordinarle alfabeticamente (tramite una funzione di ordinamento) e poi lavorarci sopra.

Non posso darti un esempio C # perché non conosco la lingua, ma questo dovrebbe essere sufficiente per te stesso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.