我在Delphi中有一個TStringList。 插入物品後,我致電.sort
程序對物品進行分類。 項目是名字後跟姓氏。例如:「約翰史密斯」。 我想按姓氏排序項目。我的意思是由空間後的第一個字符。 我該怎麼做?按空格後的第一個字符排序TStringList
而且這些項目可能是波斯字符的Unicode字符串。
我在Delphi中有一個TStringList。 插入物品後,我致電.sort
程序對物品進行分類。 項目是名字後跟姓氏。例如:「約翰史密斯」。 我想按姓氏排序項目。我的意思是由空間後的第一個字符。 我該怎麼做?按空格後的第一個字符排序TStringList
而且這些項目可能是波斯字符的Unicode字符串。
我會用CustomSort
方法TStringList
來提供自定義比較功能。首先,讓我們想象一下,我們已經得到了比較功能:
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
來執行區域識別比較。你可以通過你的StringList的每個項目迭代(可以稱之爲FullNames), 分割每個字符串,並把「分裂」兩個新的獨立的stringlists,你可以調用 FirstNameList和LastNameList。
現在創建第三個字符串列表,您可以調用ReverseFirstLast, 並將LastNameList中的項目與FirstNameList合併,並將它們放入ReverseNames中。
現在您的所有名稱都按相反順序排列。姓氏第一,名字最後。
您現在可以對ReverseFirstLast-list進行排序,並再次執行拆分&組合方法以再次反轉訂單並維護排序。
這是一種方法來完成並運行一個粗略的方法。
你可以使用的StringList的CustomSort methos:
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;
我在我的例子,我有一個名爲NameBuffer StringList的所有人的名字。然後,我將兩個按鈕添加到一個表單中,在該表單中對mylist進行排序,並將結果顯示在屏幕上。
那麼,它可以這樣做。但那會很弱。自定義比較功能是要走的路 – 2014-09-24 11:59:03