Come posso utilizzare un TEnumerator per scorrere il mio TDictionary in ordine per chiave?Come posso elencare un TDictionary in ordine alfabetico per chiave in Delphi 2009?
Ho qualcosa di simile:
var
Dic: TDictionary<string, string>;
Enum: TPair<string, string>;
begin
Dic := TDictionary<string, string>.create;
Dic.Add('Tired', 'I have been working on this too long');
Dic.Add('Early', 'It is too early in the morning to be working on this');
Dic.Add('HelpMe', 'I need some help');
Dic.Add('Dumb', 'Yes I know this example is dumb');
{ I want to do the following but do it in sorted order by Enum.Key }
for Enum in Dic do
some processing with Enum.Key and Enum.Value;
Dic.Free;
end;
quindi vorrei per elaborare il mio dizionario nell'ordine: Dumb, Early, HelpMe, Stanco.
Sfortunatamente l'aiuto di Delphi è molto minimale nel descrivere come funzionano in particolare gli enumeratori in generale e TEnumerator e non fornisce esempi che io possa trovare. C'è anche molto poco scritto sul web sull'uso degli Enumeratori con Generics in Delphi.
E il mio codice di esempio sopra non utilizza nemmeno TEnumerator, quindi sono confuso su come tutto questo è stato progettato per essere utilizzato.
Grazie Barry, per la risposta.
La mia avventura in Generics da quando ho posto la domanda era interessante. Volevo iniziare a implementarli nel mio codice. Il problema del "sorting" era un po 'perplesso, dal momento che sembra che Generics abbia dei metodi che hanno a che fare con l'ordinamento integrato, ma non ci sono buoni esempi o documentazione su come farlo.
Alla fine ho fatto quello che Barry ha suggerito e ho creato un indice esterno nel dizionario. Tuttavia, non sembra giusto.
Tuttavia, poi ho avuto un'altra sorpresa: stavo tentando di sostituire GPStringHashGabr con il TDictionary generico. Il codice era un po 'più pulito con i generici. Ma la linea di fondo era che TDictionary era oltre 3 volte più lento di quello di Gabr. 1.704.667 chiamate a TryGetValue hanno richiesto 45 secondi, ma la stessa operazione delle routine di Gabr ha richiesto 12 secondi. Non sono sicuro del perché, ma forse è semplice come Gabr che ha una funzione Hash più veloce e una combinazione di benna. O forse i generici hanno dovuto generalizzare per ogni caso e questo di per sé lo rallenta.
Mai-il-meno, forse Barry o gli altri sviluppatori Delphi dovrebbero guardare a questo, perché un aumento di velocità di 3 volte potrebbe in definitiva avvantaggiare tutti. Personalmente preferirei usare prima quello che è incorporato nella lingua rispetto a un pacchetto di terze parti (anche uno buono come quello di Gabr), se avessi la possibilità di scegliere. Ma per ora, mi limiterò a GPStringHash.
Ecco un seguito: all'inizio di quest'anno (2016), ho eseguito l'aggiornamento a Delphi XE8. Stavo pensando che TDictionary nel pacchetto Delphi Generics potrebbe essere migliorato da quando ho fatto questa domanda 5 anni fa. Così ho estratto GPStringHash da @gabr e l'ho sostituito con TDictionary. Il rallentamento del mio programma è stato abbastanza significativo. Quindi, almeno per il prossimo futuro, mi sto attaccando con GPStringHash. – lkessler
A seconda delle esigenze, anziché conservare i dati in un dizionario e occasionalmente ordinarli, è possibile fare il contrario: conservare i dati in un elenco ordinato, ma utilizzare un dizionario per l'accesso rapido "casuale". Questo si adatta meglio se si sta salvando/recuperando tramite SQL, ad esempio. Sii sempre chiaro chi possiede oggetti (archi, sei al sicuro). –