TList.SortListはQuickSortの比較関数を"const TListSortCompareFunc" = "reference to function(Item2: Pointer, Item1: Pointer): Integer;"、つまり無名メソッドで渡すことができる、というもので、従来のSortのように比較関数を別途記述する必要がありません。たとえばフォーム上にTButtonとTMemoをひとつずつ配置しておき、
type
TTestItem = class(TObject)
private
FNum: Integer;
FStr: String;
public
constructor Create(ANum: Integer; const AStr: String);
property Num: Integer read FNum;
property Str: String read FStr;
end;
constructor TTestItem.Create(ANum: Integer; const AStr: String);
begin
inherited Create;
FNum := ANum;
FStr := AStr;
end;
procedure TForm1.Button1Click(Sender: TObject);
procedure ShowList(List: TObjectList; const Caption: String);
var
Index: Integer;
TestItem: TTestItem;
begin
Memo1.Lines.Add(Caption);
for Index := 0 to List.Count - 1 do
begin
TestItem := List.Items[Index] as TTestItem;
Memo1.Lines.Add(Format('Num=%d Str=%s',
[TestItem.Num,TestItem.Str]));
end;
Memo1.Lines.Add('');
end;
var
List: TObjectList;
begin
List := TObjectList.Create(True);
try
List.Add(TTestItem.Create(5,'Five'));
List.Add(TTestItem.Create(3,'Three'));
List.Add(TTestItem.Create(1,'One'));
List.Add(TTestItem.Create(2,'Two'));
List.Add(TTestItem.Create(4,'Four'));
ShowList(List,'Before sort');
List.SortList(
function (Item1, Item2: Pointer): Integer
begin
Result := TTestItem(Item1).Num - TTestItem(Item2).Num;
end);
ShowList(List,'After sort (Num)');
List.SortList(
function (Item1, Item2: Pointer): Integer
begin
Result := CompareStr(TTestItem(Item1).Str,TTestItem(Item2).Str);
end);
ShowList(List,'After sort (Str)');
finally
List.Free;
end;
end;
こんな感じでSortListのパラメータに直接比較関数を記述できます。無名関数の記述が気持ち悪い(セミコロンの付きかたが違う、とか)という点はともかく、比較関数そのものはわかりやすく書くことができます。一方IndexOfItem/ExtractItem/RemoveItemはIndexOf/Extract/Removeに追加のパラメータとしてFromBeginning/FromEndという2値の列挙型TList.TDirectionを受け取り、これがFromBeginningならば対象アイテムを(従来通り)先頭から検索し、FromEndならば対象アイテムを末尾から検索するというバリエーションです(なぜオーバロードにせず別のシグネチャを与えたのかはわかりません)。
元ねたはMarco CantuさんのDelphi 2010 Handbook。
0 件のコメント:
コメントを投稿