delphi TStringList.CustomSort:比较()与变量

xpszyzbs  于 2023-02-04  发布在  其他
关注(0)|答案(2)|浏览(161)

我正在尝试自定义一个. 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来完成。

xe55xuns

xe55xuns1#

TStringList.CustomSort()不允许你传入额外的参数,也不接受类方法或匿名过程,但是,它所做的是将实际的TStringList本身传递给回调函数,所以我建议从TStringList派生一个新的类,向其添加额外的字段,然后你就可以在回调函数中访问这些字段,例如:

type
  TMyStringList = class(TStringList)
  public
    Count1: Integer;
    Count2: Integer;
  end;

function Compare(List: TStringList; Index1, Index2: Integer): Integer;
    ...
    p1 := GetPos(TMyStringList(List).Count1, 1);
    p2 := GetPos(TMyStringList(List).Count2, 1);
    ...
begin
  ...
end;

...

List := TMyStringList.Create;
// fill List ...
List.Count1 := ...;
List.Count2 := ...;
List.CustomSort(Compare);
jei2mxaa

jei2mxaa2#

因此,您正在搜索Ch的第k次出现,并在每次比较时创建子串。
你可以优化这个过程--在排序make list/string list数组之前,使用DelimitedText,它是从每个字符串创建的,用所需的字符分隔。
compare函数中,只处理这个数组和列号--遗憾的是,你必须将它们定义为当前单元中的全局变量(例如,在Form1: TForm1之后)

相关问题