Recent

Author Topic: How to sort objects in list  (Read 788 times)

gabriel

  • Newbie
  • Posts: 4
How to sort objects in list
« on: May 05, 2021, 12:26:52 pm »
Hey Forum

I am new to Lazarus/freepascal. I try to sort a Tlist of objects. But I get this error:
classsort.lpr(45,11) Error: Wrong number of parameters specified for call to "comparefunc".
If I change the line to:   ol.Sort(@comparefunc);  then I get this error:
classsort.lpr(45,23) Error: Incompatible type for arg no. 1: Got "<address of function(const Tobj;const Tobj):LongInt;Register>", expected "IComparer<classsort.Tobj>"
What is the correct syntax?

gabriel

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 670
Re: How to sort objects in list
« Reply #1 on: May 05, 2021, 01:34:07 pm »
Is it Generics module? You need to implement IComparer interface.

You should do it this way:
Code: Pascal  [Select][+][-]
  1. uses Generics.Defaults;
  2.  
  3. type
  4.   TMyComparer = class(TComparer<TObj>)
  5.   public
  6.     function Compare(const Left, Right: TObj): Integer; override;
  7.   end;
  8.  
30.04.2021 - DynamicData 4.0 is released and migration to it is completed.
It's more Lazarus-friendly, but still requires full Delphi 2009 support to be ported to Lazarus.
It's time to finally do it, because Delphi 2009 is 12 years old.

dbannon

  • Hero Member
  • *****
  • Posts: 1485
    • tomboy-ng, a rewrite of the classic Tomboy
Re: How to sort objects in list
« Reply #2 on: May 05, 2021, 01:40:01 pm »
Hmm, just guessing here, your compare function seems to expect two TObjects, I use plain pointers and the docs indicate that what sort() expects.  eg my code looks like this -

Code: Pascal  [Select][+][-]
  1. function LastChangeSorter( Item1: Pointer;   Item2: Pointer) : Integer;
  2. begin
  3.         result := CompareStr(PNote(Item1)^.LastChange, PNote(Item2)^.LastChange);
  4. end;

Note the pointers get '^' to say "the thing they point to", if you have been looking at Delphi code, you don't need them. You can tell FPC to treat the code as Delphi by setting the mode to Delphi but better to treat pointers as pointers IMHO.

Davo
Lazarus 2, Linux (and reluctantly Win10, OSX)
My Project - https://github.com/tomboy-notes/tomboy-ng

gabriel

  • Newbie
  • Posts: 4
Re: How to sort objects in list
« Reply #3 on: May 06, 2021, 05:15:27 pm »
Thank you Mr Madguy

I have tried to implement this ( see below) bu I get this error
sorter.pas(13,14) Error: function header doesn't match the previous declaration "compare(const Tperson;const Tperson):LongInt;"
But I have not declared enything before.
Do you have a clue ?



Code: Pascal  [Select][+][-]
  1. unit sorter;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, person, generics.Defaults;
  9.  
  10. type
  11.   Tmycomparer = class(specialize Tcomparer<Tperson>)
  12.   public
  13.     function compare(const left, right: Tperson) : integer; override;
  14. end;
  15.  
  16. implementation
  17.  
  18. function Tmycomparer.compare( const left, right: Tperson) : integer;
  19. begin
  20.   if left.navn > right.navn then result := 1
  21.   else if left.navn < right.navn then result := -1
  22.   else result := 0;
  23. end;
  24.  
  25. end.


Is it Generics module? You need to implement IComparer interface.

You should do it this way:
Code: Pascal  [Select][+][-]
  1. uses Generics.Defaults;
  2.  
  3. type
  4.   TMyComparer = class(TComparer<TObj>)
  5.   public
  6.     function Compare(const Left, Right: TObj): Integer; override;
  7.   end;
  8.  

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 670
Re: How to sort objects in list
« Reply #4 on: May 07, 2021, 10:12:49 am »
I don't have latest Lazarus version installed on my computer now. I used Delphi example. But according to this you should try to change "const" to "constref".

And you can actually try to work with comparison function via this syntax:
Code: Pascal  [Select][+][-]
  1. function MyComparison(constref Left, Right: Tperson): Integer;
  2.  
  3. ol.Sort(TComparer<Tperson>.Construct(MyComparison));
  4.  
  5. //Or this one
  6. ol.Sort(TDelegatedComparerFunc<Tperson>.Create(MyComparison));
  7.  
« Last Edit: May 07, 2021, 10:17:17 am by Mr.Madguy »
30.04.2021 - DynamicData 4.0 is released and migration to it is completed.
It's more Lazarus-friendly, but still requires full Delphi 2009 support to be ported to Lazarus.
It's time to finally do it, because Delphi 2009 is 12 years old.

 

TinyPortal © 2005-2018