在空白之后按第一个字符对TStringList进行排序

Agh*_*gha 1 delphi sorting

我在Delphi中有一个TStringList.插入项目后,我调用.sort程序对项目进行排序.物品是名字后跟姓氏.例如:"约翰史密斯".我想按姓氏对项目进行排序.我的意思是空间后的第一个角色.我怎样才能做到这一点?

而且这些项目可能是像波斯语字符一样的unicode字符串.

Dav*_*nan 5

我用CustomSort的方法TStringList来提供定制的比较功能.首先,让我们假设我们已经有了比较功能:

function NameCompareFunc(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := ...;
end;
Run Code Online (Sandbox Code Playgroud)

此函数(在适当的时候)将返回负值表示小于,正值表示大于零,零表示相等.

然后我们像这样对列表进行排序:

List.CustomSort(NameCompareFunc);
Run Code Online (Sandbox Code Playgroud)

所以,这很容易做到.但是我们如何实施NameCompareFunc?首先,我们将名称分为姓氏和其他名称.

procedure SplitName(const Name: string; out Last, Rest: string);
var
  P: Integer;
begin
  P := Pos(' ', Name);
  if P = 0 then begin
    Last := Trim(Name);
    Rest := '';
  end else begin
    Last := Trim(Copy(Name, P+1, MaxInt));
    Rest := Trim(Copy(Name, 1, P-1));
  end;
end;
Run Code Online (Sandbox Code Playgroud)

这是分割名称的一种非常天真的方式.您可能希望从名称末尾开始搜索分隔符,但我会让您决定如何执行此操作.

现在我们可以实现比较功能:

function NameCompareFunc(List: TStringList; Index1, Index2: Integer): Integer;
var
  Last1, Last2, Rest1, Rest2: string;
begin
  SplitName(List[Index1], Last1, Rest1);
  SplitName(List[Index2], Last2, Rest2);
  Result := AnsiCompareText(Last1, Last2);
  if Result = 0 then begin
    Result := AnsiCompareText(Rest1, Rest2);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

一些说明:

  1. 我假设名称比较应始终不区分大小写.
  2. 我们AnsiCompareText用来执行区域设置感知比较.
  3. 如果我们遇到两个具有相同姓氏的名称,那么我们将对名称的其余部分进行二次比较.