我在Delphi中有一个TStringList。
插入项目后,我调用.sort
程序对项目进行排序。
物品是名字后跟姓氏。例如:" John Smith"。
我想按姓氏对项目进行排序。我的意思是空间后的第一个角色。
我怎么能这样做?
并且这些项目也可以是像波斯语字符一样的unicode字符串。
答案 0 :(得分:5)
我使用TStringList
的{{3}}方法提供自定义比较功能。首先,让我们想象一下我们已经有了比较功能:
function NameCompareFunc(List: TStringList; Index1, Index2: Integer): Integer;
begin
Result := ...;
end;
此函数将(在适当的时候)返回负值表示小于,正值表示大于零,零表示相等。
然后我们按如下方式对列表进行排序:
List.CustomSort(NameCompareFunc);
所以,这很容易做到。但是我们如何实施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;
这是分割名称的一种非常天真的方式。您可能希望从名称末尾开始搜索分隔符,但我们会让您决定如何执行此操作。
现在我们可以实现比较功能:
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;
一些注意事项:
AnsiCompareText
执行区域设置感知比较。答案 1 :(得分:3)
您可以使用Stringlist的CustomSort方法:
function LastNameCompareStrings(List: TStringList; Index1, Index2: Integer): Integer;
var
S1, S2: string;
SpaceIndex: Integer;
begin
S1 := List[Index1];
SpaceIndex := Pos(' ', S1);
if SpaceIndex <> 0 then
S1 := Copy(S1, 1, SpaceIndex - 1);
S2 := List[Index2];
SpaceIndex := Pos(' ', S2);
if SpaceIndex <> 0 then
S2 := Copy(S2, 1, SpaceIndex - 1);
if List.CaseSensitive then
Result := AnsiCompareStr(S1, S2)
else
Result := AnsiCompareText(S1, S2);
end;
procedure TForm7.ButtonFirstNameClick(Sender: TObject);
begin
NameBuffer.Sort;
Memo1.Lines.Assign(NameBuffer);
end;
procedure TForm7.ButtonLastNameClick(Sender: TObject);
begin
NameBuffer.CustomSort(@LastNameCompareStrings);
Memo1.Lines.Assign(NameBuffer);
end;
我的例子我在StringList中有你所有的名字,叫做NameBuffer。然后我在表单中添加了两个按钮,我将其分类为mylist,并在屏幕上显示结果。
答案 2 :(得分:0)
您可以迭代StringList的每个项目(让我们称之为FullNames), 拆分每个字符串并将“拆分”放在两个可以调用的新单独的字符串列表中 FirstNameList和LastNameList。
现在创建第三个字符串列表,您可以调用ReverseFirstLast, 并将LastNameList中的项与FirstNameList合并,并将它们放在ReverseNames中。
现在您的所有名称都按相反的顺序排列。姓氏优先,姓氏最后。
您现在可以对ReverseFirstLast列表进行排序,并再次执行split&amp; combine方法再次撤消订单并维护排序。
这是一种方法,可以让一个粗略的方法启动并运行。