2
Make a locate of a dataset connected to the bank, certainly is quite costly. But make a locate in a dataset with in-memory data only, is a good practice? Or would it be better to create a array?
Grateful.
2
Make a locate of a dataset connected to the bank, certainly is quite costly. But make a locate in a dataset with in-memory data only, is a good practice? Or would it be better to create a array?
Grateful.
2
Here is a simple example of using the Dictionary.
unit Unit2;
interface
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  System.Generics.Collections, Vcl.StdCtrls;
type
  TPessoa = class
    id: integer;
    nome: string;
    sobrenome: string;
    idade: integer;
    sexo: string;
  end;
  TListaPessoa = TObjectList<TPessoa>;
  TForm2 = class(TForm)
    btnBuscarPessoa: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btnBuscarPessoaClick(Sender: TObject);
  private
    FListaPessoa: TListaPessoa;
    FDicionarioPessoa: TDictionary<integer, TPessoa>;
    procedure AdicionarPessoas;
    procedure AlimentarDicionario;
  end;
var
  Form2: TForm2;
implementation
uses
  StrUtils;
{$R *.dfm}
procedure TForm2.AdicionarPessoas;
var
  i: integer;
begin
  for i := 1 to 10000 do
  begin
    FListaPessoa.Add(TPessoa.Create);
    FListaPessoa.Last.id        := i;
    FListaPessoa.Last.nome      := 'Nome' + IntToStr(Random(1000));
    FListaPessoa.Last.sobrenome := 'Sobrenome' + IntToStr(Random(1000));
    FListaPessoa.Last.idade     := Random(80);
    FListaPessoa.Last.sexo      := IfThen(odd(FListaPessoa.Last.id + FListaPessoa.Last.idade), 'M', 'F');
  end;
end;
procedure TForm2.AlimentarDicionario;
var
  FPessoa: TPessoa;
begin
  for FPessoa in FListaPessoa do
    if (not(FDicionarioPessoa.ContainsKey(FPessoa.id))) then
      FDicionarioPessoa.Add(FPessoa.id, FPessoa);
end;
procedure TForm2.FormCreate(
  Sender:
  TObject);
begin
  FListaPessoa      := TListaPessoa.Create;
  FDicionarioPessoa := TDictionary<integer, TPessoa>.Create;
  AdicionarPessoas;
  AlimentarDicionario;
end;
procedure TForm2.btnBuscarPessoaClick(Sender: TObject);
var
  identificador: integer;
begin
  identificador := Random(10000);
  ShowMessage(
    'A pessoca com o id ' + IntToStr(identificador) + ' é ' + FDicionarioPessoa.Items[identificador].nome + ' ' + FDicionarioPessoa.Items[identificador].sobrenome +
    ' tem ' + IntToStr(FDicionarioPessoa.Items[identificador].idade) + ' anos de idade e é do sexo ' +
    IfThen(FDicionarioPessoa.Items[identificador].sexo = 'M', 'masculino', 'feminino')
    );
end;
end.
Note that the legal methods of the Dictionary are the ContainsKey or ContainsValue.
Note: In the test I did, I put 7000000 records, and the search is instant.
Note 2:Data ordering is also fast with data dictionary.
Thank you very much and congratulations for the example, very detailed and practical! @Victor Zanella
Aaah, I forgot to tell you, but the classes could be interfaces. In this case I forgot to release the created objects.
1
It is more expensive in processing. Mainly because with each new execution of locate, you would have to position the record at the beginning of Dataset.
A better option would be to use Findkey([]).
To use it, you only need to configure and use an index in Dataset and use the fields in Findkey.
Ex:
cdsDataSet.IndexDefs.add('IDX_NOME','CAMPO1;CAMPO2;CAMPO3',[]);
cdsDataSet.IndexName := 'IDX_NOME';
// Observe que você não precisa passar todos os campos do índice
// Mas precisa seguir sempre a mesma ordem.
if cdsDataSet.FindKey([_valorCampo1, _valorCampo2]) then
  showMessage('Achei')
else
  ShowMessage('não achei');
Browser other questions tagged delphi
You are not signed in. Login or sign up in order to post.
Have you considered the possibility of using a
TDictionary?– Victor Tadashi
@Victorzanella No, you can give more details about the operation of
TDictionary?– Andrey
just to confirm, which version of Delphi you are using ?
– Victor Tadashi
@Victorzanella Delphi XE7
– Andrey