Antes de nada, indicar que se puede leer el post original de Zarko Gajic aquí.
Esta es una traducción del post original al español.
Introducido en Delphi 2009, la clase TDictionary , definida en la unidad Generics.Collections, representa una colección genérica de tablas de tipo hash de pares clave-valor .
Los tipos genéricos, de nuevo introducidos en Delphi 2009, permiten definir clases en la cual no se definen específicamente el tipo de dato.
Un diccionario es, en cierto modo, similar a una matriz. Una matriz tiene una serie (colección) de valores indexados (a menudo) por un entero (puede ser cualquier valor de tipo ordinal ). Este índice tiene, como mínimo, un límite superior a uno.
Un diccionario tiene claves y valores, donde las claves y los valores pueden ser de cualquier tipo.
Por lo tanto la declaración del constructor TDictionary:
TDictionary<TKey, TValue>.Create;
En Delphi, la TDictionary se define como una tabla hash. Las tablas hash representa una colección de claves y pares de valores que se organizan en función del código hash de la clave. Las tablas hash se han optimizado para las búsquedas (de velocidad). Cuando un par clave-valor se agrega a una tabla hash, el hash de la clave se calcula y se almacena junto con el par de añadidos.
El TKey y TValue (ya que los medicamentos genéricos) puede ser de cualquier tipo. Por ejemplo, si la información que han de almacenar en el diccionario viene de alguna base de datos, la clave puede ser un GUID (o algún otro valor que presenta el índice único) de valor, mientras que el valor puede ser un objeto asignado a una fila de datos en las tablas de bases de datos.
Usando TDictionary
En aras de la simplicidad del ejemplo siguiente utiliza números enteros para las teclas y caracteres de los valores. Vamos a ver cómo hacer las operaciones básicas con los diccionarios:
// // "log" is a TMemo control placed on a form // var dict : TDictionary<integer, char>; sortedDictKeys : TList<integer>; i, rnd : integer; c : char; begin log.Clear; log.Text := 'TDictionary usage samples'; Randomize; dict := TDictionary<integer, char>.Create; try //add some key/value pairs (random integers, random characters from A in ASCII) for i := 1 to 20 do begin rnd := Random(30); if NOT dict.ContainsKey(rnd) then dict.Add(rnd, Char(65 + rnd)); end; //remove some key/value pairs (random integers, random characters from A in ASCII) for i := 1 to 20 do begin rnd := Random(30); dict.Remove(rnd); end; //loop elements - go through keys log.Lines.Add('ELEMENTS:'); for i in dict.Keys do log.Lines.Add(Format('%d, %s', [i, dict.Items[i]])); //do we have a "special" key value if dict.TryGetValue(80, c) then log.Lines.Add(Format('Found "special", value: %s', [c])) else log.Lines.Add(Format('"Special" key not found', [])); //sort by keys ascending log.Lines.Add('KEYS SORTED ASCENDING:'); sortedDictKeys := TList.Create(dict.Keys); try sortedDictKeys.Sort; //default ascending for i in sortedDictKeys do log.Lines.Add(Format('%d, %s', [i, dict.Items[i]])); finally sortedDictKeys.Free; end; //sort by keys descending log.Lines.Add('KEYS SORTED DESCENDING:'); sortedDictKeys := TList.Create(dict.Keys); try sortedDictKeys.Sort(TComparer.Construct( function (const L, R: integer): integer begin result := R - L; end )) ; for i in sortedDictKeys do log.Lines.Add(Format('%d, %s', [i, dict.Items[i]])); finally sortedDictKeys.Free; end; finally dict.Free; end; end;
En primer lugar, declaramos nuestro diccionario, especificando cuáles son los tipos de la TKey y TValue serán los siguientes:
dict : TDictionary;
El diccionario está lleno de mediante el método Add. Desde un diccionario no se puede tener dos pares con el mismo valor de clave, puede utilizar el método ContainsKey para comprobar si algún valor de par de claves ya está dentro del diccionario.
Para eliminar un par del diccionario, el método Remove se puede utilizar. Nótese que Quitar no causará problemas si un par con una clave especificada no es una parte del diccionario.
Para pasar por todas las parejas saltando a través de las teclas que usted puede hacer un bucle en el .
El método TryGetValue se puede utilizar para comprobar si algún par valor de clave está incluido en el diccionario.
El Diccionario de Clasificación
Dado que un diccionario es una tabla hash que no almacena los elementos de un orden de clasificación. Si desea iterar a través de las teclas que se ordenan (en la forma que desee) usted puede tomar ventaja de la TList (De nuevo un tipo de colección genérica), que admite la ordenación.
El código anterior teclas ordena ascendente (y descendente) y toma valores como si estuvieran almacenados en la forma ordenada en el diccionario. Tenga en cuenta que la clasificación de la descendente (tipo entero) Los valores clave utiliza TComparer y un método anónimo.
Cuando las claves y los valores son de tipo TObject
Como se ha dicho, el ejemplo anterior es muy simple ya que tanto la clave y el valor son tipos simples.
Por supuesto, usted puede tener diccionarios complejas en las que tanto la clave y el valor sería «complejos» como los tipos de registros u objetos.
He aquí otro ejemplo:
type TMyRecord = record Name, Surname : string end; TMyObject = class(TObject) Year, Value : integer; end; procedure TForm2.logDblClick(Sender: TObject); var dict : TObjectDictionary<TMyRecord, TMyObject>; myR : TmyRecord; myO : TMyObject; begin dict := TObjectDictionary<TMyRecord, TMyObject>.Create([doOwnsValues]); try myR.Name := 'Zarko'; myR.Surname := 'Gajic'; myO := TMyObject.Create; myO.Year := 2012; myO.Value := 39; dict.Add(myR, myO); myR.Name := 'Zarko'; myR.Surname := '?????'; if NOT dict.ContainsKey(myR) then log.Lines.Add('not found'); finally dict.Free; end; end;
Aquí la costumbre de registro se utiliza para la clave y un objeto personalizado / clase se utiliza para el valor.
Nótese el uso de una clase TObjectDictionary especializada aquí. TObjectDictionary tiene la capacidad para manejar la vida de los objetos de forma automática.
El valor llave no puede ser nulo, mientras que el valor de valor posible.
Cuando un TObjectDictionary se crea una instancia, un parámetro PARTICIPACIONES especifica si el diccionario posee las llaves, los valores, o ambos – y por lo tanto le ayuda a no tener pérdidas de memoria .
Deja una respuesta