Ordenação de TObjectList
Muitas vezes utilizamos listas de objetos (TObjectList) para agrupar clientes, contatos, produtos, etc.
Pode ser que os dados sejam adicionados a lista sem uma ordenação lógica, ordenação esta que pode vir a ser necessária.
A classe
TObjectList possui o método Sort que possui a seguinte assinatura:
procedure Sort(Compare: TListSortCompare);
O parâmetro Compare é do tipo TListSortCompare que deve ser uma função com a seguinte assinatura
TListSortCompare = function (Item1, Item2: Pointer): Integer;
Como vocês podem ver, para ordenar a lista será necessário criar uma função de ordenação utilizando a regra que desejarmos.
Exemplo de função de ordenação
Para exemplificar vou criar uma classe Item, uma lista de Itens(TItemList) e duas funções de ordenação.
type
TItem = class(TObject)
private
FName: string;
FID: Integer;
procedure SetID(const Value: Integer);
procedure SetName(const Value: string);
public
property ID : Integer read FID write SetID;
property Name : string read FName write SetName;
end;
TItemList = class(TObjectList)
public
function Add(AObject: TItem): Integer;
end;
function SortAscending(Item1, Item2: Pointer): Integer;
var Obj1 : TItem;
Obj2 : TItem;
begin
Obj1 := TItem(Item1);
Obj2 := TItem(Item2);
if Obj1.ID > Obj2.ID then
Result := +1
else
if Obj1.ID < Obj2.ID then
Result := -1
else
Result := 0;
end;
function SortDescending (Item1, Item2: Pointer): Integer;
var Obj1 : TItem;
Obj2 : TItem;
begin
Obj1 := TItem(Item1);
Obj2 := TItem(Item2);
if Obj1.ID > Obj2.ID then
Result := -1
else
if Obj1.ID < Obj2.ID then
Result := +1
else
Result := 0;
end;
Agora um exemplo de utilização das classes e funções. Será utilizado um laço para gerar aleatoriamente 10 ID diferentes para preencher um componente Memo na ordem de geração e depois em Ordem Crescente e Decrescente.
var Item : TItem;
List : TItemList;
idx : Integer;
ID : Integer;
begin
Memo1.Lines.Clear;
Memo1.Lines.Add('Ordem de Geração');
List := TItemList.Create;
for idx := 1 to 10 do
begin
ID := Random(99) + 1;
Item := TItem.Create;
Item.ID := ID;
Item.Name := Format('Item%.3d', [ID]);
List.Add(Item);
Memo1.Lines.Add(Format('ID=%.3d', [Item.ID]));
end;
Memo1.Lines.Add('=====');
Memo1.Lines.Add('Ordem Ascendente');
List.Sort(SortAscending);
for idx := 0 to List.Count -1 do
begin
Item := List[idx] AS TItem;
Memo1.Lines.Add(Format('ID=%.3d', [Item.ID]));
end;
Memo1.Lines.Add('=====');
Memo1.Lines.Add('Ordem Descendente');
List.Sort(SortDescending);
for idx := 0 to List.Count -1 do
begin
Item := List[idx] AS TItem;
Memo1.Lines.Add(Format('ID=%.3d', [Item.ID]));
end;
end;
Este código irá gerar uma saída semelhante a esta:
Ordem de Geração
ID=063
ID=090
ID=078
ID=009
ID=067
ID=026
ID=045
ID=083
ID=027
ID=073
=====
Ordem Ascendente
ID=009
ID=026
ID=027
ID=045
ID=063
ID=067
ID=073
ID=078
ID=083
ID=090
=====
Ordem Descendente
ID=090
ID=083
ID=078
ID=073
ID=067
ID=063
ID=045
ID=027
ID=026
ID=009
Como vocês viram é simples gerar a função de ordenação, seria possível ordenar por data, nome ou qualquer outra propriedade presente nos Objetos da Lista.
Até a próxima :D
3 comentários: