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