Recent

Author Topic: [soled] StringList.CustomSort - how to migrate from Delphi?  (Read 3267 times)

Nicole

  • Hero Member
  • *****
  • Posts: 1308
[soled] StringList.CustomSort - how to migrate from Delphi?
« on: September 09, 2022, 04:02:07 pm »
For the person, who knows the answer, it should be very easy.
I used in Delphi StringList.CustomSort and see in Lazarus StringList.CustomSort "wrong number of parameters".
For me it looks the same, - what do I have to change?
Thanks!

Below is the call and the function. Both works in Delph (and as the parameter are different, I do not understand why by myself. It is really old code):

Code: Pascal  [Select][+][-]
  1.  SL_SUB.CustomSort(StringListSortComparefn2);


Code: Pascal  [Select][+][-]
  1. function TFrame_Korrelationen.StringListSortComparefn2(List: TStringList; Index1, Index2: Integer): Integer;
  2. var  i: Integer;
  3.      s:string;
  4.      d1, d2: double;
  5.      gueltig: Boolean;
  6.  
  7. begin // in List werden die gegeneinander zu sortierenden Zeilen übergeben
  8.  
  9.   result:=0;  d1:=0; d2:=0;
  10.   If (List[Index1] = '') or (List[Index2] = '') then exit;
  11.  
  12.   i:=0;
  13.  
  14.   s:=List[Index1];
  15.   i:=AnsiPos(':',s);  // 'AD Korrelation zu BO: -15,3%'
  16.   if (i < 1) then exit; // bei Null wird es nicht gefunden
  17.   s:=copy(s, i+1,Length(s));
  18.   s:=Trim(s);
  19.   s:=copy(s, 0, Length(s) -1);
  20.   Trim(s);
  21.   gueltig:=TryStrToFloat(s,d1);
  22.   if gueltig=false then exit; // absichtlich keine Fehlermeldung, können zuviele werden!
  23.   d1:=Abs(d1);
  24.  
  25.   s:=List[Index2];
  26.   i:=AnsiPos(':',s);  // 'AD Korrelation zu BO: -15,3%'
  27.   if (i < 1) then exit; // bei Null wird es nicht gefunden
  28.   s:=copy(s, i+1,Length(s));
  29.   s:=Trim(s);
  30.   s:=copy(s, 0, Length(s) -1);
  31.   Trim(s);
  32.   gueltig:=TryStrToFloat(s,d2);
  33.   if gueltig=false then exit; // absichtlich keine Fehlermeldung, können zuviele werden!
  34.   d2:=Abs(d2);
  35.  
  36.   if d1=d2 then result:=0;      // beide Einträge haben die gleiche Sortier-Reihenfolge
  37.   if d1 > d2 then result:= 1;   // Sortierreihenfolge, allenfalls +/- vertauschen
  38.   if d1 < d2 then result:= -1;
  39.  
  40. end;
                                       
« Last Edit: September 15, 2022, 02:49:37 pm by Nicole »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12766
  • FPC developer.
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #1 on: September 09, 2022, 04:10:09 pm »
To be Delphi compatible, use $mode Delphi.

Nicole

  • Hero Member
  • *****
  • Posts: 1308
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #2 on: September 09, 2022, 04:17:44 pm »
Thank you for the answer.
I changed it to
{$mode Delphi}{$H+}
not sure, what H means.

and: It did not help in the Sort-thing.

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #3 on: September 09, 2022, 04:18:33 pm »
i tested with default {$mode objfpc}{$H+} switch.
no error, no hint, no warning.

can you provide a screenshot or some small demo app?
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #4 on: September 09, 2022, 04:21:26 pm »
what H means
Hints  :)

turn hints on/off
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Nicole

  • Hero Member
  • *****
  • Posts: 1308
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #5 on: September 09, 2022, 04:24:55 pm »
To me the problem seems quite obvious (what may be my fault):
The parameters of the declaration are 3 of them, the call contains only one parameter.

Any ideas, how I can change the call?
(who suspects, I have not understood customsort in the depth is right)

bytebites

  • Hero Member
  • *****
  • Posts: 778
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #6 on: September 09, 2022, 04:27:20 pm »
The compare function can't be instance function. Move it away from the frame.
Code: Pascal  [Select][+][-]
  1. function StringListSortComparefn2(List: TStringList; Index1, Index2: Integer): Integer;

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #7 on: September 09, 2022, 04:28:17 pm »
To me the problem seems quite obvious (what may be my fault):
The parameters of the declaration are 3 of them, the call contains only one parameter.

Any ideas, how I can change the call?
(who suspects, I have not understood customsort in the depth is right)

Code: Pascal  [Select][+][-]
  1.  SL_SUB.CustomSort(@StringListSortComparefn2);

Bitteschön  :-*
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

rvk

  • Hero Member
  • *****
  • Posts: 6989
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #8 on: September 09, 2022, 04:45:19 pm »
what H means
Hints  :)

turn hints on/off
YIKES. No no.

https://www.freepascal.org/docs-html/prog/progsu25.html
{$H+} means Use AnsiStrings

For {$MODE DELPHI} the {$H+} is default and can be ommited.
For {$MODE OBJFPC} you do need {$H+} if you want to use AnsiStrings.

(To avoid confusion it's best to always put {$H+} after the $MODE switch)

BTW Hints is {$HINTS ON} or {$HINTS OFF}
https://www.freepascal.org/docs-html/prog/progsu27.html#x34-330001.2.27

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12766
  • FPC developer.
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #9 on: September 09, 2022, 05:08:44 pm »
And delphi mode should not require a @. If so that is a bug, and you need to file it.

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #10 on: September 09, 2022, 06:10:24 pm »
TStringList is a rather slow and not memory efficient structure, maybe aimed at mimicking Microsoft COM similar component.

Since now FPC more or less support Generics - as long as you need just a container better use TList<string> as long as you would not use extended features. And when you did - extended string lists, like Jedi CodeLib's iJclStringList are still better than stock TStringList :-D

And then you can do this: https://stackoverflow.com/questions/13252169/how-do-i-sort-a-generic-list-using-a-custom-comparer

Code: Pascal  [Select][+][-]
  1. function _MyCompare(constref Left, Right: string): Integer;  // Delphi would only have const, not constref
  2. begin
  3.    Result := ....
  4. end;
  5.  
  6. type
  7.   _iMyComparator = specialize IComparer<string>; // you would not need "specialize" in FPC's Delphi mode or in Delphi
  8.  
  9. function _MyComparator: _iMyComparator;
  10. begin
  11.   Result := specialize TComparer<string>.Construct( @_MyCompare );
  12. end;
  13.  
  14. var Found: boolean;
  15.  
  16. procedure DoSomething;
  17. var
  18.   listSmall, listBig: specialize TList<string>;
  19.   notlist: array of string;
  20.   cmp: _iMyComparator;
  21.   idx: SizeInt;
  22. begin
  23.   listSmall := nil;
  24.   listBig := nil;
  25.   try
  26.     listSmall := specialize TList<string>.Create;
  27.     listBig := specialize TList<string>.Create;
  28.    
  29.     listSmall.Add('dfgsdfsdfsd');
  30.     listSmall.Add('534908450');  
  31.  
  32.     SetLength(notlist, 2);
  33.     notlist[0] := 'gtrrwetretger';
  34.     notlist[1] := '95840834';
  35.  
  36.     // not necessary to have a special variable, but since i would use more than one
  37.     //  time - it is a bit better to cache one than to create new object one every use
  38.     cmp := _MyComparator();
  39.  
  40.     listSmall.Sort(cmp);
  41.     specialize TArrayHelper<string>.Sort(notlist, cmp);
  42.  
  43.     listBig.AddRange(notlist);
  44.     listBig.AddRange(listSmall);
  45.  
  46.     DoSomethingExternal(listBig.ToArray());
  47.  
  48.     // or with ad hoc creation
  49.    
  50.     Found := specialize TArrayHelper<RDiagRow>.BinarySearch(
  51.            notlist, 'SERFSDFSE',  idx,
  52.            specialize TComparer<string>.Construct( @_MyCompare )
  53.     );
  54.  
  55.   finally
  56.     listBig.Free;
  57.     listSmall.Free;
  58.   end;
  59. end;
« Last Edit: September 09, 2022, 06:16:37 pm by Arioch »

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #11 on: September 09, 2022, 06:20:03 pm »
what H means
Hints  :)

turn hints on/off
YIKES. No no.

https://www.freepascal.org/docs-html/prog/progsu25.html
{$H+} means Use AnsiStrings

For {$MODE DELPHI} the {$H+} is default and can be ommited.
For {$MODE OBJFPC} you do need {$H+} if you want to use AnsiStrings.

(To avoid confusion it's best to always put {$H+} after the $MODE switch)

BTW Hints is {$HINTS ON} or {$HINTS OFF}
https://www.freepascal.org/docs-html/prog/progsu27.html#x34-330001.2.27
Dayum, i was told wrong, i am sorry i did not wanted to confuse, thank you for correcting me!!!
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Nicole

  • Hero Member
  • *****
  • Posts: 1308
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #12 on: September 10, 2022, 02:18:37 pm »
This is really helpful.
We shall rename you in KodeRiese. I like your postings.

The issue itself about the stringList is not resolved, I am stuck and will post the solution or a small project soon.

jamie

  • Hero Member
  • *****
  • Posts: 7653
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #13 on: September 10, 2022, 03:50:30 pm »
Having a hard time following this thread.

 The short function isn't an object/Class type, you should be supplying an address to the sort function outside the class.

TStringList.CustomShort(@MyNornalSortFunction);

Something of that order.

 Also, consider the fact that maybe you have UF8 chars in your strings and thus should be using UTF8 features inside the sort function?

 Btw.
   Object type methods have a background parameter (SELF) that you don't see and thus the function for the sort does note expect this.

 This is just pure theory on my part, but I am good at that :D
The only true wisdom is knowing you know nothing

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #14 on: September 10, 2022, 03:58:03 pm »
It does not work in Delphi either, unless that comparato method would be class static function, which si not a method at all, but a global function hidden inside the class namespace.

Delphi XE2 error is attached.

Just like bytebites said - make this functon global.

Quote
The parameters of the declaration are 3 of them, the call contains only one parameter.

I think you are wrong here, twice.

  • the call to TStringList.CustomSort has only one single parameter - the functon to be called by StringList. A pointer to a function with specific signaure. Read any Pascal tutorial about procedure types.
  • your function TFrame_Korrelationen.StringListSortComparefn2(List: TStringList; Index1, Index2: Integer): Integer; does not have three paramaeters, it had FOUR parameters. You forgot about Self, which is a parameter too, albeit "hidden" or "invisible" one. This 4th paramneter is exactly why TStringList can not call this your function.

It is possible, though, that you used not the Delphi stock TStringList, but some extended, 3rd party string list, that has a number of overloaded CustomSort functions consuming many different comparer types, including the 4-parameter  function (x, y, z):T OF OBJECT datatype

It is also possible that recent Delphi would re-define TStringListSortCompare datatypeto be REFERENCE TO function(x,y,z):T. This would work slower but be more flexible.

I wonder if FPC's stock TStringList could be extended to have two more CustomSort methods, including function(string,string) and function(stringlist, integer, integer) of object comparators.

While it would make things a bit slower i do not think performance is very pressing concern for TStringList
« Last Edit: September 10, 2022, 04:00:03 pm by Arioch »

 

TinyPortal © 2005-2018