Delphi: Criando uma lista associada simples
Já abordei em outro tópico a utilização de vetores no Delphi. O vetores do Delphi são ótimos porem seria ótimo se nativamente permitissem acessar um item através de uma string, conforme o exemplo:
procedure Teste; var vetor : array of integer; begin vetor['valor1'] = 2; end;
Infelizmente isso não é possível, porem poder implementar tal recurso.
Inicialmente idealizei um classe para executar essa tarefa da seguinte forma:
type
TVarArray = class
private
FKeys : array of Variant;
FValues : array of Variant;
FSize : integer;
FDefaultValue: Variant;
function GetValue(Index: Variant): Variant;
procedure SetValue(Index: Variant; const Value: Variant);
procedure SetSize(ASize : integer);
public
property Size : integer read FSize;
procedure Clear;
constructor Create;
function ValueFromIndex(Index: integer): variant;
function KeyFromIndex(Index: Integer): Variant;
function IndexOf(Value : Variant): integer;
property DefaultValue: Variant read FDefaultValue write FDefaultValue;
property Values[Key : Variant]: Variant read GetValue write SetValue; default;
end;
Após implementada essa classe me permitirá (alem da funcionalidade já mensionada) verificar seu tamanho(Size), limpa-la(Clear), percorrer as chaves (KeyFromIndex) e valores (ValueFromIndex) e verificar a existência de um valor (IndexOf). Então vamos ao código detalhado e explicado:
procedure TVarArray.SetSize(ASize: integer); begin FSize := ASize; SetLength(FKeys, ASize); SetLength(FValues, ASize); end; procedure TVarArray.Clear; begin SetSize(0); end;
Aqui temos a função responsável por limpar nossa lista, definindo seu tamanho para 0 (zero). A função SetSize recebe o tamanho e redimensiona o vetor com as chaves e com os valores, essa mesma função sera usada na inserção de valores mais a frente.
function TVarArray.IndexOf(Value: Variant): integer;
var
i : integer;
begin
for i := Length(FKeys) - 1 downto 0 do
if FKeys[i] = Value then
Break;
Result := i;
end;
Aqui temos a função que retorna a posição de uma chave na lista, ou -1 caso não seja encontrada.
function TVarArray.ValueFromIndex(Index: integer): variant;
begin
if Index >= FSize then
Result := FDefaultValue
else
Result := FValues[Index];
end;
function TVarArray.KeyFromIndex(Index: Integer): Variant;
begin
if (Index >= FSize) or (Index < 0) then
Result := FDefaultValue
else
Result := FKeys[Index];
end;
Parecido com a anterior porem retornando valores em função do índice recebido as funções ValueFromIndex e KeyFromIndex retorna o valor e a chave de cada índice da lista respectivamente.
function TVarArray.GetValue(Index: Variant): Variant;
var
idx : Integer;
begin
idx := IndexOf(Index);
if idx = -1 then
Result := FDefaultValue
else
Result := FValues[idx];
end;
Enfim a chegamos a parte que retorna cada valor da propriedade Values, nessa parte uma chave é procurada na lista (IndexOf) caso encontradas o valor de mesmo indice na lista de valores é retornado, caso contrario o valor padrão (DefaltValue) será retornado.
procedure TVarArray.SetValue(Index: Variant; const Value: Variant);
var
idx : integer;
begin
idx := IndexOf(Index);
if idx = -1 then
begin
idx := Length(FKeys);
SetSize(idx + 1);
FKeys[idx] := Index;
end;
FValues[idx] := Value;
end;
O SetValue é quem comanda a inserção de um item na lista caso o mesmo não seja encontrado. Depois disso o valor é coloca na lista (Seja no novo item ou no encontrado).
constructor TVarArray.Create; begin inherited; FDefaultValue := Null; SetSize(0); end;
Por fim mais não menos importante tempo o construtor da classe que define o valor padrão para Null e o tamanho inicial da lista para 0 (zero).
O código fonte completo pode ser encontrado aqui. Todo o trabalho desenvolvido aqui pode ser feito através de um dicionário. Porem para as versões mais antigas no Delphi onde esse recurso não está disponível, e também para fins didáticos essa continua sendo uma implementação útil.