----- Original Message ----- 
From: "Dave Sellers" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Friday, June 03, 2005 2:13 PM
Subject: [list] [delphi-en] TObjectList.Sort issues


> I'm using TObjectList.Sort successfully but, I suspect, not particularly
> elegantly. In fact, I have a suspicion I'm doing something dumb..

I've gone ahead and knocked up an extended TObjectList class, to support 
object method comparison methods.  Apologies if this source is longer than 
should be posted to the list.

Regards

Walter


==================================
unit uObjectListEx;

{ 04/06/2005: The TObjectListEx extends TObjectList to allow slightly more 
object
  oriented delegation of the sort responsibility (ie, it expects an object 
method to be
  supplied to the Sort call, as opposed to a pure function pointer, as 
present in TObjectList.)
  A pure funtion pointer is sometimes problematic in contexts where the sort 
operation requires access
  to context held in an object. This extension help avoid some of that 
awkwardness, though it
  still requires typecasting in the supplied sort method to get at sort 
object properties. }

interface

uses Contnrs;

type
  TObjectListSortCompareMethod = function (Obj1, Obj2 : TObject) : Integer 
of Object;
  TObjectListEx = class(TObjectList)
  private
    procedure QuickSort(L, R: Integer;
      SCompare: TObjectListSortCompareMethod);
  public
    procedure Sort(CompareMethod: TObjectListSortCompareMethod);
  end;

implementation

{ TObjectListEx }

procedure  TObjectListEx.QuickSort(L, R: Integer;
  SCompare: TObjectListSortCompareMethod);
var
  I, J: Integer;
  P, T: Pointer;
begin
  { 04/06/2005: This method is based on QuickSort procedure from 
Classes.pas, (c) Borland Software Corp.
    but modified to be part of TObjectListEx class.  It implements the 
standard quicksort algorithm,
    delegating comparison operation to an object method.  The Borland 
version delegates to a pure function
    pointer, which is problematic in some cases.}
  repeat
    I := L;
    J := R;
    P := List^[(L + R) shr 1];
    repeat
      while SCompare(TObject(List^[I]), P) < 0 do
        Inc(I);
      while SCompare(TObject(List^[J]), P) > 0 do
        Dec(J);
      if I <= J then
      begin
        T := List^[I];
        List^[I] := List^[J];
        List^[J] := T;
        Inc(I);
        Dec(J);
      end;
    until I > J;
    if L < J then
      QuickSort(L, J, SCompare);
    L := I;
  until I >= R;
end;

procedure TObjectListEx.Sort(CompareMethod: TObjectListSortCompareMethod);
begin
  if (List <> nil) and (Count > 0) then
    QuickSort(0, Count - 1, CompareMethod);
end;

end.
==================================
unit uObjectListExTestForm;

{Demo/Test form for TObjectListEx}

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uObjectListEx, StdCtrls;

type
  // a little class used for demo/testing
  TSortObj = class
    Name : String;
    constructor Create(AName : String);
  end;

  TObjectListExTestForm = class(TForm)
    Memo: TMemo;
    SortButton: TButton;
    PopulateMemoButton: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure SortButtonClick(Sender: TObject);
    procedure PopulateMemoButtonClick(Sender: TObject);
  private
    { Private declarations }
    FObjectlist : TObjectListEx;
    function MyCompareMethod(Obj1, Obj2 : TObject) : Integer;
  public
    { Public declarations }
  end;

var
  ObjectListExTestForm: TObjectListExTestForm;

implementation

{$R *.dfm}

{ TSortObj }

constructor TSortObj.Create(AName: String);
begin
  Name := AName;
end;

{ TObjectListExTestForm }

procedure TObjectListExTestForm.FormCreate(Sender: TObject);
begin
  FObjectList := TObjectListEx.Create;
  FObjectList.OwnsObjects := True;
  FObjectList.Add(TSortObj.Create('John'));
  FObjectList.Add(TSortObj.Create('Peter'));
  FObjectList.Add(TSortObj.Create('Zelda'));
  FObjectList.Add(TSortObj.Create('Amelie'));
end;

procedure TObjectListExTestForm.FormDestroy(Sender: TObject);
begin
  FObjectlist.Free
end;

procedure TObjectListExTestForm.SortButtonClick(Sender: TObject);
begin
  FObjectlist.Sort(MyCompareMethod);
end;

function TObjectListExTestForm.MyCompareMethod(Obj1, Obj2: TObject): 
Integer;
var
  SortObj1, SortObj2 : TSortObj;
begin
  SortObj1 := TSortObj(Obj1);
  SortObj2 := TSortObj(Obj2);
  result := CompareStr(SortObj1.Name, SortObj2.Name);
end;

procedure TObjectListExTestForm.PopulateMemoButtonClick(Sender: TObject);
var
  ObjIndex : Integer;
begin
  Memo.Lines.Clear;
  for ObjIndex := 0 to FObjectlist.Count -1 do
    Memo.Lines.Add(TSortObj(FObjectList[ObjIndex]).Name);
end;

end.





-----------------------------------------------------
Home page: http://groups.yahoo.com/group/delphi-en/
To unsubscribe: [EMAIL PROTECTED] 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/delphi-en/

<*> To unsubscribe from this group, send an email to:
    [EMAIL PROTECTED]

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 


Reply via email to