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 件のコメント:
コメントを投稿