TObjectlist 里边的 sort 排序功能如何用(100)

  • 主题发起人 主题发起人 okgxsh
  • 开始时间 开始时间
O

okgxsh

Unregistered / Unconfirmed
GUEST, unregistred user!
如果 这个list 里我 add了一个对象 liststore name :='wang' Sex :='Man'如果我增加了很多这个 liststore对象我如何用 TObjectlist 里边的sort函数排序呢?
 
TListSortCompare = function (Item1, Item2: Pointer): Integer;procedure Sort(Compare: TListSortCompare);自己写一个原型为 TListSortCompare 函数, 调用就可以了
 
function TFieldHolderIndexSorter(ptOne, ptTwo: Pointer):Integer; var holderOne,holderTwo : Tliststore; begin holderOne := Tliststore(ptOne); holderTwo := Tliststore(ptTwo); if Length(holderOne.name ) > Length(holderTwo.name ) then result := 1 else if Length(holderOne.name ) = Length(holderTwo.name ) then result := 0 else result := -1; end;不知道这个东西写的对不对
 
procedure QuickSort(SortList: PPointerList; L, R: Integer; SCompare: TListSortCompare);var I, J: Integer; P, T: Pointer;begin repeat I := L; J := R; P := SortList^[(L + R) shr 1]; repeat while SCompare(SortList^, P) < 0 do Inc(I); while SCompare(SortList^[J], P) > 0 do Dec(J); if I <= J then begin T := SortList^; SortList^ := SortList^[J]; SortList^[J] := T; Inc(I); Dec(J); end; until I > J; if L < J then QuickSort(SortList, L, J, SCompare); L := I; until I >= R;end;procedure TList.Sort(Compare: TListSortCompare);begin if (FList <> nil) and (Count > 0) then QuickSort(FList, 0, Count - 1, Compare);end;---------------------------------------------------------将函数带入即可,看似没什么问题,主要是看自己的排序规则。
 
如果 这个list 里我 add了一个对象 liststore name :='wang' Sex :='Man'我对这个 name 和sex 进行排序,怎么带入呢,比较困惑
 
针对Name和Sex分别写一个函数,如TFieldHolderIndexSorter_NameTFieldHolderIndexSorter_Sex想使用什么方法排序就调用对应的函数啊。不过你自己的函数TFieldHolderIndexSorter是根据长度来计算的,而不是根据字符串大小进行排序的,改写一下:function TFieldHolderIndexSorter(ptOne, ptTwo: Pointer):Integer;begin Result:=AnsicompareText( Tliststore(ptOne).name, Tliststore(ptTwo).name );end;
 
TObjectlist排序的时候比较函数要你自己写.否则他怎么知道你的比较规则呢.呵呵
 
写了 一个:这个需要循环很多次排序,是不是写的有问题:unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,Contnrs;Type TNameInfo = class(TPersistent) public FName : string; FSex : string; end; TWagerList = class(TObjectList) private function GetWager(wIndex: integer): TNameInfo; public property Wagers[windex:integer]: TNameInfo read GetWager; Function AddStore:boolean; end;type TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; Button2: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1; MyWagerList : TWagerList;implementation{$R *.dfm}{ TWagerList }function TWagerList.AddStore: boolean;var WagerS : TNameInfo; i :integer;begin for i := 1 to 1000 do begin WagerS := TNameInfo.Create; WagerS.FName :='SY'; WagerS.FSex :='R5'; add(WagerS); WagerS := TNameInfo.Create; WagerS.FName :='SY'; WagerS.FSex :='R4'; add(WagerS); WagerS := TNameInfo.Create; WagerS.FName :='SS'; WagerS.FSex :='R5'; add(WagerS); WagerS := TNameInfo.Create; WagerS.FName :='SY'; WagerS.FSex :='R4'; add(WagerS); WagerS := TNameInfo.Create; WagerS.FName :='SY'; WagerS.FSex :='R3'; add(WagerS); WagerS := TNameInfo.Create; WagerS.FName :='SY'; WagerS.FSex :='R5'; add(WagerS); WagerS := TNameInfo.Create; WagerS.FName :='SS'; WagerS.FSex :='R5'; add(WagerS); WagerS := TNameInfo.Create; WagerS.FName :='SY'; WagerS.FSex :='R4'; add(WagerS); WagerS := TNameInfo.Create; WagerS.FName :='SY'; WagerS.FSex :='R3'; add(WagerS); WagerS := TNameInfo.Create; WagerS.FName :='SY'; WagerS.FSex :='R5'; add(WagerS); end;end;function TWagerList.GetWager(wIndex: integer): TNameInfo;begin begin if (wIndex < 0) or (wIndex >= Count) then begin result := nil; exit; end; Result := TNameInfo(Items[wIndex]);end;end;procedure TForm1.FormCreate(Sender: TObject);begin MyWagerList := TWagerList.Create; MyWagerList.AddStore;end;function TFieldHolderIndexSorter(ptOne, ptTwo: Pointer):Integer; var holderOne,holderTwo : TNameInfo; begin holderOne := TNameInfo(ptOne); holderTwo := TNameInfo(ptTwo); if holderOne.FName = holderTwo.FName then begin if (holderOne.FSex) <> (holderTwo.FSex) then result := 1 else if (holderOne.FSex) = (holderTwo.FSex) then result := 0 else result := -1; end else begin if (holderOne.FSex) <> (holderTwo.FSex) then result := 1 else if (holderOne.FSex) = (holderTwo.FSex) then result := 0 else result := -1; end end;procedure TForm1.Button1Click(Sender: TObject);var i :integer; Str: string;begin for i := 0 to 10 do MyWagerlist.Sort(@TFieldHolderIndexSorter);{ for i := 0 to 9999 do Str := Str + #13#10 + MyWagerList.Wagers.FName +'>>' + MyWagerList.Wagers.FSex; Memo1.Lines.Add( Str);}end;procedure TForm1.Button2Click(Sender: TObject);var i :integer; Str: string;begin for i := 0 to 9999 do Str := Str + #13#10 + MyWagerList.Wagers.FName +'>>' + MyWagerList.Wagers.FSex; Memo1.Lines.Add( Str);end;end.
 
procedure TForm1.Button1Click(Sender: TObject);var i :integer; Str: string;begin for i := 0 to 9999 do //这里需要循环这么多次,才能最后排序完成,哪里优化一下?? MyWagerlist.Sort(@TFieldHolderIndexSorter);{ for i := 0 to 9999 do Str := Str + #13#10 + MyWagerList.Wagers.FName +'>>' + MyWagerList.Wagers.FSex; Memo1.Lines.Add( Str);}end;
 
更改如下,测试通过:{第一排序为姓名,第二排序为性别,你写的代码中,无论姓名是否相同,都是根据性别来判断的,且只区分了性别的2中情况,至于第三种情况,else result := -1;是不可能执行到的。 }function TFieldHolderIndexSorter(ptOne, ptTwo: Pointer): Integer;var holderOne, holderTwo: TNameInfo;begin holderOne := TNameInfo(ptOne); holderTwo := TNameInfo(ptTwo); result:= Ansicomparetext( holderOne.FName, holderTwo.FName ); if result=0 then result:= ansicomparetext( holderOne.FSex, holderTwo.FSex );end;procedure TForm1.Button1Click(Sender: TObject);begin MyWagerlist.Sort(@TFieldHolderIndexSorter);end;procedure TForm1.Button2Click(Sender: TObject);var i: integer; Str: string;begin Memo1.Lines.Clear; Memo1.Lines.BeginUpdate; for i := 0 to 9999 do Memo1.Lines.Add( MyWagerList.Wagers.FName + '>>' + MyWagerList.Wagers.FSex ); Memo1.Lines.EndUpdate;end;
 
谢谢!thanks
 
后退
顶部