2013-09-03 24 views
7

Non sono un esperto di C# e LINQ.Creazione di un dizionario ordinato utilizzando ToDictionary

Ho un Dictionary, che capisco una tabella hash, cioè, le chiavi non sono ordinate.

dataBase = new Dictionary<string, Record>() 

Record è una classe definita dall'utente che contiene un numero di dati per una determinata stringa chiave.

ho trovato un esempio interessante che converte questo Dictionary in un ordinato dizionario da LINQ:

var sortedDict = (from entry in dataBase orderby entry.Key ascending select entry) 
.ToDictionary(pair => pair.Key, pair => pair.Value); 

Questo codice funziona correttamente. Il risultato sortedDict è ordinato per chiavi.

Domanda: ho scoperto che sortedDict è ancora una tabella hash, un tipo di:

System.Collections.Generic.Dictionary<string, Record> 

Mi aspettavo il dizionario risultante dovrebbe essere una sorta di map come in C++ STL, che è generalmente implementato come un albero binario (bilanciato) per mantenere l'ordine delle chiavi. Tuttavia, il dizionario risultante è ancora una tabella hash.

In che modo sortedDict è possibile mantenere l'ordine? Una tabella hash non può contenere l'ordinamento delle chiavi. L'implementazione di C23 è Generic.Dictionary diversa da una tipica tabella hash?

+1

Utilizzando 'ToDictionary()', si chiesto e ottenuto un 'dizionario'. Se vuoi mantenere un Diecionario ordinato, usa 'SortedDictionary' – TheEvilPenguin

+1

lo so. Ma, ho bisogno di un dizionario ordinato all'ultimo momento. La mia domanda è che come 'Dictionary' può mantenere l'ordine, che è strano per me.Il codice LINQ crea effettivamente un dizionario * ordinato *, mentre il tipo è ancora un dizionario. – minjang

+0

Il linq ordina semplicemente 'Dictionary', non crea un' SortedDictionary' –

risposta

7

Dictionary mantiene due strutture dati: una matrice piatta che è tenuto in ordine di inserimento per l'enumerazione e la tabella di hash per il recupero per chiave.

Se si utilizza ToDictionary() su un set ordinato, sarà in ordine quando enumerato, ma non verrà mantenuto in ordine. Tutti gli elementi appena inseriti verranno aggiunti sul retro durante l'enumerazione.

Modifica: se si desidera fare affidamento su questo comportamento, è consigliabile consultare i documenti MSDN per verificare se sono garantiti o solo occasionali.

7

SortedDictionary prende uno Dictionary esistente nel costruttore in modo da rendere un SortedDictionary molto semplice.

Ma si può rendere un metodo di estensione, se si desidera, è possibile utilizzare dataBase.ToSortedDictionary()

public static SortedDictionary<K, V> ToSortedDictionary<K,V>(this Dictionary<K, V> existing) 
{ 
    return new SortedDictionary<K, V>(existing); 
} 
2

il codice linq sembra costruire un dizionario ordinato, ma l'ordinamento viene eseguito dal linq, non dal dizionario stesso, mentre un SortedDictionary dovrebbe mantenere l'ordinamento da solo.

per ottenere un dizionario ordinato, utilizzare new SortedDictionary<string, Record>(yourNormalDictionary);

se si vuole rendere più accessibile, allora si può scrivere un'estensione al IEnumerable:

public static class Extensions 
{ 
    public static SortedDictionary<T1, T2> ToSortedDictionary<T1, T2>(this IEnumerable<T2> source, Func<T2, T1> keySelector) 
    { 
     return new SortedDictionary<T1, T2>(source.ToDictionary(keySelector)); 
    } 
} 
Problemi correlati