I am trying to sort a list of strings with text and numbers: |
Normal text sorting goes like: |
But I want: |
---|---|---|
Team 1 | Team 1 | Team 1 |
Team 2 | Team 10 | Team 2 |
Team 10 | Team 12 | Team 10 |
Team 12 | Team 2 | Team 12 |
Team 20 | Team 20 | Team 20 |
Team 21 | Team 21 | Team 21 |
These are user-entered strings, could also be T101
, T102
, T301
etc. (these could be easier). I don't want to try to reinvent the wheel, but I have not been able to find a Pascal example which does the job.
More details: The items I need to sort are in fact in a TObjectList
, which has to be sorted by TSARPanel.RefName
:
TSARPanel = class(TObject)
...
RefName: String;
...
end;
TSARPanelList = class(TObjectList)
private
function GetRecord(AIndex: Integer): TSARPanel;
procedure SetRecord(AIndex: Integer; const AValue: TSARPanel);
public
property Items[AIndex: Integer]: TSARPanel read GetRecord write SetRecord; default;
...
end;
Based on Remy's example, how do I manage to convert it into a TArray<String>
based sort?
If you are on a more recent Delphi version, you can make use of TStringHelper.Compare()
and the coDigitAsNumbers
option. This example is using Delphi 12:
uses
System.SysUtils,
System.Generics.Collections,
System.Generics.Defaults;
procedure Main;
begin
var arr := TArray<string>.Create('Team 1', 'Team 10', 'Team 12', 'Team 2', 'Team 20', 'Team 21');
TArray.Sort<string>(arr, TDelegatedComparer<string>.Create(
function(const Left, Right: string): Integer
begin
Result := string.Compare(Left, Right, [coDigitAsNumbers]);
end
));
for var S in arr do
Writeln(S);
end;
Update: Based on your question update, a solution for your case could be like this:
SARPanelList.SortList(
function (Item1, Item2: Pointer): Integer
begin
Result := string.Compare(TSARPanel(Item1).RefName, TSARPanel(Item2).RefName);
end
);