Delphi: Criando uma lista associada simples

26 de setembro de 2011 william Delphi

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.

delphi,


Deixe uma resposta

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Powered by WordPress. Designed by elogi.