Lazarus

Programming => General => Topic started by: gabriel on May 05, 2021, 12:26:52 pm

Title: How to sort objects in list
Post by: gabriel 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
Title: Re: How to sort objects in list
Post by: Mr.Madguy 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.  
Title: Re: How to sort objects in list
Post by: dbannon 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
Title: Re: How to sort objects in list
Post by: gabriel 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.  
Title: Re: How to sort objects in list
Post by: Mr.Madguy 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 (https://github.com/graemeg/freepascal/blob/2d3976f39531ea8fe167600014bd3069f333b52d/packages/rtl-generics/src/generics.defaults.pas) 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.  
TinyPortal © 2005-2018