I am an intermediate Delphi programmer that needs to learn a lot so I hope my question here is not to dumb. I have a file with 1546 strings that I need to place in a StringList and do a custom sort. The strings look like this:
2:X,X,2,2,2,X<A>11
7:5,7,7,6,5,5<A>08
3:3,X,0,0,1,0<C/D>11
5:X,2,4,2,5,2<Asus2/Gb>02
3:0,3,2,0,3,0<C/D>02
4:X,0,4,4,0,0<Asus2/Gb>11
4:X,X,4,4,4,2<B>01
3:3,2,1,0,0,3<B#5>11
I need them to look like this:
2:X,X,2,2,2,X<A>11
7:5,7,7,6,5,5<A>08
5:X,2,4,2,5,2<Asus2/Gb>11
4:X,0,4,4,0,0<Asus2/Gb>02
4:X,X,4,4,4,2<B>01
3:3,2,1,0,0,3<B#5>11
3:3,X,0,0,1,0<C/D>11
3:0,3,2,0,3,0<C/D>02
They need to be sorted by the portion of the string between the <...> and the last 2 chars. Any help would be much appreciated.
OK...done, Works quite well. Sorts a list with over 1500 strings in 62ms. Constructive criticism will be appreciated.
function SortChords(List:TStringList; idx1,idx2:integer): integer;
var
s1,s2:string;
begin
s1:=List[idx1];
s1:=copy(s1,pos('<',s1)+1,pos('>',s1)-pos('<',s1)-1);
s2:=List[idx2];
s2:=copy(s2,pos('<',s2)+1,pos('>',s2)-pos('<',s2)-1);
if s1 < s2 then
result:=-1
else if s1 > s2 then
result:=1
else
result:=0;
end;
You can write your own custom sort procedure and use TStringList.CustomSort to sort in the desired order.
The following demonstrates using the custom sort. It does not produce the exact output you describe, because you're not clear how you determine the precedence of two items that have the same value between the <> (as in lines 1 and 2, or 3 and 4, of your expected output; you can add code to decide the final order where I've indicated in the code comment. The sample is a complete console application that demonstrates sorting the values you've provided. It's slightly verbose in variable declarations for clarity.
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes;
function ListSortProc(List: TStringList; Index1, Index2: Integer): Integer;
var
StartPosA, EndPosA: Integer;
StartPosB, EndPosB: Integer;
TestValA, TestValB: string;
Comp: Integer;
begin
StartPosA := Pos('<', List[Index1]) + 1;
EndPosA := Pos('>', List[Index1]);
TestValA := Copy(List[Index1], StartPosA, EndPosA - StartPosA);
StartPosB := Pos('<', List[Index2]) + 1;
EndPosB := Pos('>', List[Index2]);
TestValB := Copy(List[Index2], StartPosB, EndPosB - StartPosB);
Result := CompareStr(TestValA, TestValB);
{ To do further processing for lines with the same value, add
code here.
if Result = 0 then
// Decide on the order of the equal values with whatever
// criteria you want.
}
end;
var
SL: TStringList;
s: String;
begin
SL := TStringList.Create;
try
SL.Add('2:X,X,2,2,2,X<A>11');
SL.Add('7:5,7,7,6,5,5<A>08');
SL.Add('3:3,X,0,0,1,0<C/D>11');
SL.Add('5:X,2,4,2,5,2<Asus2/Gb>02');
SL.Add('3:0,3,2,0,3,0<C/D>02');
SL.Add('4:X,0,4,4,0,0<Asus2/Gb>11');
SL.Add('4:X,X,4,4,4,2<B>01');
SL.Add('3:3,2,1,0,0,3<B#5>11');
SL.CustomSort(ListSortProc);
for s in SL do
WriteLn(s);
ReadLn;
finally
SL.Free;
end;
end.
The code above produces this output:
7:5,7,7,6,5,5<A>08
2:X,X,2,2,2,X<A>11
4:X,0,4,4,0,0<Asus2/Gb>11
5:X,2,4,2,5,2<Asus2/Gb>02
4:X,X,4,4,4,2<B>01
3:3,2,1,0,0,3<B#5>11
3:0,3,2,0,3,0<C/D>02
3:3,X,0,0,1,0<C/D>11