2014-09-29 15 views
12

Ho una funzione in cui memorizzo alcune coppie di valori-chiave e quando eseguo l'iter ricevo questo errore due volte: [Errore dcc32] App.pas (137): E2149 La classe non ha una proprietà predefinita. Qui fa parte del mio codice:Delphi TDictionary iteration

function BuildString: string; 
var 
    i: Integer; 
    requestContent: TDictionary<string, string>; 
    request: TStringBuilder; 
begin 
    requestContent := TDictionary<string, string>.Create(); 

    try 
    // add some key-value pairs 
    request := TStringBuilder.Create; 
    try 
     for i := 0 to requestContent.Count - 1 do 
     begin 
     // here I get the errors 
     request.Append(requestContent.Keys[i] + '=' + 
      TIdURI.URLEncode(requestContent.Values[i]) + '&'); 
     end; 

     Result := request.ToString; 
     Result := Result.Substring(0, Result.Length - 1); //remove the last '&' 
    finally 
     request.Free; 
    end; 
    finally 
    requestContent.Free; 
    end; 
end; 

ho bisogno di raccogliere le informazioni da ogni elemento presente nel dizionario. Come posso ripararlo?

+2

'var S: stringa; Coppia: TPair ; iniziare per Pair in YourDictionary do S: = Pair.Key + Pair.Value; fine; ' – TLama

+1

Usa' per AKey in requestContent.Keys fa begin request.Append (AKey + '=' + TIdURI.Encode (requestContent [AKey]) + '&'); ... etc.'. Devi dichiarare 'AKey' come stringa, ovviamente. –

+2

@RudyVelthuis Con i dizionari, è quasi sempre meglio iterare su coppie che su chiavi, che invariabilmente si traducono in codice più efficiente. Nel caso del dizionario Delphi, l'iteratore della coppia evita qualsiasi necessità di calcolare l'hash codici, ed eseguire sondaggi –

risposta

25

Le proprietà della classe del dizionario sono TDictionary<string, string>.TKeyCollection e TDictionary<string, string>.TValueCollection rispettivamente. Queste classi derivano da TEnumerable<T> e non possono essere iterate dall'indice. È comunque possibile eseguire iterazioni su Keys o, in effetti, su Values, non sul fatto che quest'ultimo potrebbe essere molto utile per l'utente.

Se ripetuti su Keys il codice potrebbe essere simile:

var 
    Key: string; 
.... 
for Key in requestContent.Keys do 
    request.Append(Key + '=' + TIdURI.URLEncode(requestContent[Key]) + '&'); 

Questo invece è inefficiente. Dal momento che si sa che si desidera sia il valore chiave e di corrispondenza, è possibile utilizzare iteratore del dizionario:

var 
    Item: TPair<string, string>; 
.... 
for Item in requestContent do 
    request.Append(Item.Key + '=' + TIdURI.URLEncode(Item.Value) + '&'); 

La coppia iteratore è più efficiente rispetto alla prima variante di cui sopra. Questo perché i dettagli di implementazione significa che la coppia iteratore è in grado di iterare il dizionario senza:

  1. Calcolo codici hash per ogni tasto, e
  2. Performing scansione lineare quando i codici hash si scontrano.
Problemi correlati