我正在尝试自定义一个. CSV文件中的TStringList的列排序。下面的代码可以工作(很慢,大约14秒200,000行):
function Compare(List: TStringList; Index1, Index2: Integer): Integer;
function ColStr(const Ch: Char; const S: String; First, Last: Integer): String;
var
p1, p2: Integer;
function GetPos(const N: Integer; Start: Integer = 1): Integer;
var
I, Len, Count: Integer;
begin
Result := 0;
Len := Length(S);
if (Len = 0) or (Start > Len) or (N < 1) then Exit;
Count := 0;
for I := Start to Len do begin
if S[I] = Ch then begin
Inc(Count);
if Count = N then begin
Result := I;
Exit;
end;
end;
end;
end;
begin
p1 := GetPos(4, 1); // 4 should be a variable
p2 := GetPos(5, 1); // 5 should be a variable
if Last = 0 then Result := Copy(S, p1 + 1, length(S)) else Result := Copy(S, p1 + 1, p2 - p1 - 1);
end;
begin
Result := AnsiCompareStr(ColStr(',', List[Index1], 0, 1), ColStr(',', List[Index2], 0, 1));
end;
我想做的是不要硬编码but(其中注解的"* 应该是变量 *"取决于要排序的列)。
function Form1.Compare(List: TStringList; Index1, Index2: Integer): Integer;
插入变量时,我得到了错误:
不兼容的类型:"方法指针和常规过程"。
我已经搜索了,所以寻找这个错误的例子,但找不到一个符合我的问题。我将不胜感激任何指针在正确的方向。
这必须用Delphi 7和Windows 11来完成。
2条答案
按热度按时间xe55xuns1#
TStringList.CustomSort()
不允许你传入额外的参数,也不接受类方法或匿名过程,但是,它所做的是将实际的TStringList
本身传递给回调函数,所以我建议从TStringList
派生一个新的类,向其添加额外的字段,然后你就可以在回调函数中访问这些字段,例如:jei2mxaa2#
因此,您正在搜索
Ch
的第k次出现,并在每次比较时创建子串。你可以优化这个过程--在排序make list/string list数组之前,使用
DelimitedText
,它是从每个字符串创建的,用所需的字符分隔。在
compare
函数中,只处理这个数组和列号--遗憾的是,你必须将它们定义为当前单元中的全局变量(例如,在Form1: TForm1
之后)