自定义排序字符串列表
Custom Sort Stringlist
我是一名中级 Delphi 程序员,需要学习很多东西,所以我希望我的问题不是愚蠢的。我有一个包含 1546 个字符串的文件,我需要将其放入 StringList 中并进行自定义排序。字符串如下所示:
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
我需要它们看起来像这样:
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
它们需要按 <...> 和最后 2 个字符之间的字符串部分进行排序。任何帮助将非常感激。
好的...完成,效果很好。在 62 毫秒内对包含 1500 多个字符串的列表进行排序。建设性的批评将 表示赞赏 。
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;
您可以编写自己的自定义排序程序并使用 TStringList.CustomSort 按所需顺序排序。
下面演示使用自定义排序。它不会产生您描述的确切输出,因为您不清楚如何确定 <> 之间具有相同值的两个项目的优先级(如预期输出的第 1 行和第 2 行,或第 3 行和第 4 行; 您可以添加代码来决定我在代码注释中指出的最终顺序。该示例是一个完整的控制台应用程序,演示了对您提供的值进行排序。为清楚起见,它在变量声明中略显冗长。
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.
上面的代码产生了这个输出:
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
我是一名中级 Delphi 程序员,需要学习很多东西,所以我希望我的问题不是愚蠢的。我有一个包含 1546 个字符串的文件,我需要将其放入 StringList 中并进行自定义排序。字符串如下所示:
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
我需要它们看起来像这样:
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
它们需要按 <...> 和最后 2 个字符之间的字符串部分进行排序。任何帮助将非常感激。
好的...完成,效果很好。在 62 毫秒内对包含 1500 多个字符串的列表进行排序。建设性的批评将 表示赞赏 。
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;
您可以编写自己的自定义排序程序并使用 TStringList.CustomSort 按所需顺序排序。
下面演示使用自定义排序。它不会产生您描述的确切输出,因为您不清楚如何确定 <> 之间具有相同值的两个项目的优先级(如预期输出的第 1 行和第 2 行,或第 3 行和第 4 行; 您可以添加代码来决定我在代码注释中指出的最终顺序。该示例是一个完整的控制台应用程序,演示了对您提供的值进行排序。为清楚起见,它在变量声明中略显冗长。
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.
上面的代码产生了这个输出:
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