Custom Sort Delphi TStringList name / value pairs as integers

I have a couple of Name / Value TStringList elements. Names are integer values, which are usually stored as strings), and values ​​are all strings (separated by commas).

eg.

5016=Catch the Fish!,honeyman,0
30686=Ozarktree1 Goes to town,ozarktreel,0

. ,.

I would like to call the add procedure and add new lines to the TStringlist, but you need a way to sort the list later.

eg.

Tags.Add(frmTag.edtTagNo.Text + '=' +
         frmTag.edtTitle.Text + ',' +
         frmTag.edtCreator.Text + ',' +
         IntToStr(ord(frmTag.cbxOwned.Checked)));
Tags.Sort;

Here is what I tried:

Tags:= TStringList.Create;
 Tags.CustomSort(StringListSortComparefn);
 Tags.Sorted:= True;

my usual sorting procedure:

function StringListSortComparefn(List: TStringList; Index1, Index2: Integer): Integer;
var
 i1, i2 : Integer;
begin
 i1 := StrToIntDef(List.Names[Index1], 0);
 i2 := StrToIntDef(List.Names[Index2], 0);
 Result:= CompareValue(i1, i2);
end;

However, still it seems they are sorting them as strings instead of integers.

I even tried to create my own class:

type
 TXStringList = class(TStringList)
 procedure Sort;override;
end;

implementation

function StringListSortComparefn(List: TStringList; Index1, Index2: Integer): Integer;
var
i1, i2 : Integer;
begin
i1 := StrToIntDef(List.Names[Index1], 0);
i2 := StrToIntDef(List.Names[Index2], 0);
Result:= CompareValue(i1, i2);
end;

procedure TXStringList.Sort;
begin
 CustomSort(StringListSortComparefn);
end;

I even tried several examples on SO (e.g. Sorting the TSTringList Names property as integers instead of strings )

- , ? , .

30686=Ozarktree1 Goes to town,ozarktreel,0
5016=Catch the Fish!,honeyman,0
+4
3

:

function StringListSortComparefn(List: TStringList; Index1, Index2: Integer): Integer;
var
 i1, i2 : Integer;
begin
 i1 := StrToIntDef(List.Names[Index1], 0);
 i2 := StrToIntDef(List.Names[Index2], 0);
 Result := i1 - i2
end;

, :

Result := i2 - i1;

:

program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils, Classes;

function StringListSortProc(List: TStringList; Index1, Index2: Integer): Integer;
var
  i1, i2: Integer;
begin
  i1 := StrToIntDef(List.Names[Index1], -1);
  i2 := StrToIntDef(List.Names[Index2], -1);
  Result := i1 - i2;
end;

var
  SL: TStringList;
  s: string;
begin
  SL := TStringList.Create;
  SL.Add('3456=Line 1');
  SL.Add('345=Line 2');
  SL.Add('123=Line 3');
  SL.Add('59231=Line 4');
  SL.Add('545=Line 5');
  WriteLn('Before sort');
  for s in SL do
    WriteLn(#32#32 + s);
  SL.CustomSort(StringListSortProc);
  WriteLn('');
  WriteLn('After sort');
  for s in SL do
    WriteLn(#32#32 + s);
  ReadLn;
  SL.Free;
end.

:

Before sort
  3456=Line 1
  345=Line 2
  123=Line 3
  59231=Line 4
  545=Line 5

After sort
  123=Line 3
  345=Line 2
  545=Line 5
  3456=Line 1
  59231=Line 4
+6

, ? , , .

, . CustomSort , .

  Tags := tStringList . Create;
  Tags . Add ( '5016=Catch the Fish!,honeyman,0' );
  Tags . Add ( '30686=Ozarktree1 Goes to town,ozarktreel,0' );
  Tags.CustomSort(StringListSortComparefn);

, CompareStrings.

type
 TXStringList = class(TStringList)
    function CompareStrings(const S1, S2: string): Integer; override;
end;

function NumberOfNameValue ( const S : string ) : integer;
begin
  Result := StrToIntDef(copy(S,1,pos('=',S)-1), 0);
end;

function txStringList . CompareStrings ( const S1, S2 : string ) : integer;
var
 i1, i2 : Integer;
begin
 i1 := NumberOfNameValue ( S1 );
 i2 := NumberOfNameValue ( S2 );
 Result:= CompareValue(i1, i2);
end;


begin
  Tags := txstringlist . Create;
  Tags . Sorted := true;
  Tags . Add ( '5016=Catch the Fish!,honeyman,0' );
  Tags . Add ( '30686=Ozarktree1 Goes to town,ozarktreel,0' );
 // List will be correctly sorted at this point. 
end;
+3

CustomSort . , , , , , . ( , ) . , Sorted, , , , .

Sort, , ( Sorted=True) Sort! , . Sort CompareStrings:

type
  TXStringList = class(TStringList)
  protected
    function CompareStrings(const S1, S2: string): Integer; override;
  end;

function TXStringList.CompareStrings(const S1, S2: string): Integer;
var
  i1, i2, e1, e2: Integer;
begin
  Val(S1, i1, e1);
  Assert((e1 = 0) or (S1[e1] = NameValueSeparator));
  Val(S2, i2, e2);
  Assert((e2 = 0) or (S2[e2] = NameValueSeparator));
  Result := CompareValue(i1, i2);
end;

, IndexOf. Find, , , . (Find - , , .) CompareStrings, Sort.

+3
source

Source: https://habr.com/ru/post/1534651/


All Articles