Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 5 of 5 total
Thread TObjectlist.sort
Tue, Mar 17 2020 5:47 PMPermanent Link

Bruno Larochelle

Hello, I have tried to use the TObjectlist.sort functionality but I can't seem to get it to work quite right.

I created a new object based on TObjectlist and overrode the 2 sortcompare functions.

  TSortedTimeList = class(TObjectList)
     function SortCompare(L,R: TObject): Integer; override;
     function SortCompare(L: TObject; const R: String): Integer; override;


No matter what I do it seems to always infinitely loop as soon as it tries to sort, ultimately it doesn't even seem enter my routines as I tried throwing a showmessage in there and it never popped up.
Tue, Mar 17 2020 6:41 PMPermanent Link

Raul

Team Elevate Team Elevate

On 3/17/2020 5:47 PM, Bruno Larochelle wrote:
> Hello, I have tried to use the TObjectlist.sort functionality but I can't seem to get it to work quite right.
>
> I created a new object based on TObjectlist and overrode the 2 sortcompare functions.
>
>     TSortedTimeList = class(TObjectList)
>        function SortCompare(L,R: TObject): Integer; override;
>        function SortCompare(L: TObject; const R: String): Integer; override;
> No matter what I do it seems to always infinitely loop as soon as it tries to sort, ultimately it doesn't even seem enter my routines as I tried throwing a showmessage in there and it never popped up.

What do you actually do you do in those functions - what's your
implementation ?

I have used this and it works OK.

One issue i did run into it think was that you should return one of
CMP_LESS, CMP_EQUAL and CMP_GREATER as a result (-1,0,1 respectively).

I think i f i did not sort was off

Raul
Tue, Mar 17 2020 6:53 PMPermanent Link

Bruno Larochelle

Raul wrote:

On 3/17/2020 5:47 PM, Bruno Larochelle wrote:
> Hello, I have tried to use the TObjectlist.sort functionality but I can't seem to get it to work quite right.
>
> I created a new object based on TObjectlist and overrode the 2 sortcompare functions.
>
>     TSortedTimeList = class(TObjectList)
>        function SortCompare(L,R: TObject): Integer; override;
>        function SortCompare(L: TObject; const R: String): Integer; override;
> No matter what I do it seems to always infinitely loop as soon as it tries to sort, ultimately it doesn't even seem enter my routines as I tried throwing a showmessage in there and it never popped up.

What do you actually do you do in those functions - what's your
implementation ?

I have used this and it works OK.

One issue i did run into it think was that you should return one of
CMP_LESS, CMP_EQUAL and CMP_GREATER as a result (-1,0,1 respectively).

I think i f i did not sort was off

Raul



Was trying to sort a custom list of objects based on a date.

function TSortedTimeList.SortCompare(L,R: TObject): Integer;
begin           
  if Integer(TSortedTimeItem(L).aTime) < Integer(TSortedTimeItem(R).aTime) then result := CMP_LESS
  else if Integer(TSortedTimeItem(L).aTime) > Integer(TSortedTimeItem(R).aTime) then result := CMP_GREATER
  else result := CMP_EQUAL;
end;
Tue, Mar 17 2020 7:15 PMPermanent Link

Raul

Team Elevate Team Elevate

On 3/17/2020 6:53 PM, Bruno Larochelle wrote:
> Was trying to sort a custom list of objects based on a date.
>
> function TSortedTimeList.SortCompare(L,R: TObject): Integer;
> begin
>     if Integer(TSortedTimeItem(L).aTime) < Integer(TSortedTimeItem(R).aTime) then result := CMP_LESS
>     else if Integer(TSortedTimeItem(L).aTime) > Integer(TSortedTimeItem(R).aTime) then result := CMP_GREATER
>     else result := CMP_EQUAL;
> end;

That looks OK to me.

Are you setting list sorted := true or only sorting later ?

How many items in your list ?

I recall adding LogOutput into this and it was called a lot but was
still fast - though i had only 100s of objects.


I just tried a quick test and this works ok for me for 1000 objects -
final list is properly sorted

type

TPerson = class(TObject)
   public
     Age:integer;
   end;

   TMyPersonObjectList = class(TObjectList)
   protected
     function SortCompare(L,R: TObject): Integer; override;
     function SortCompare(L: TObject; const R: String): Integer; override;
   end;

....

function TMyPersonObjectList.SortCompare(L,R: TObject): Integer;
begin
   result := (TPerson(L).Age-TPerson(R).Age);
   if result < 0 then
      result := CMP_LESS
   else if result > 0 then
      result := CMP_GREATER
   else
      result := CMP_EQUAL;
end;

function TMyPersonObjectList.SortCompare(L: TObject; const R: String):
Integer;
begin
   Result := CompareText(TPerson(L).ClassName,R);
end;

....

procedure TForm1.Button1Click(Sender: TObject);
var
   i:integer;
   ml:TMyPersonObjectList;
   p:TPerson;
begin
   ml := TMyPersonObjectList.Create(true);
   ml.Sorted := true;
   for i := 999 downto 1 do
   begin
      p := TPerson.Create;
      p.Age := i;
      ml.Add(p);
   end;

   for i := 0 to ml.Count-1 do
   begin
      MultiLineEdit1.Lines.Add( inttostr(TPerson(ml[i]).Age));
   end;

   ml.free;
end;



Raul

Tue, Mar 17 2020 8:25 PMPermanent Link

Bruno Larochelle

  TSortedTimeList = class(TObjectList)
  protected
     function SortCompare(L,R: TObject): Integer; override;
     function SortCompare(L: TObject; const R: String): Integer; override;



Looking at your example I noticed I didn't have my functions set as protected. I added protected to this and it all seems to work now.  Thank you very much I had a feeling it would be something like that.
Image