2014-09-24 61 views
1

我在Delphi中有一個TStringList。 插入物品後,我致電.sort程序對物品進行分類。 項目是名字後跟姓氏。例如:「約翰史密斯」。 我想按姓氏排序項目。我的意思是由空間後的第一個字符。 我該怎麼做?按空格後的第一個字符排序TStringList

而且這些項目可能是波斯字符的Unicode字符串。

回答

5

我會用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; 

一些注意事項:

  1. 我假設比較名稱應始終不區分大小寫。
  2. 我們使用AnsiCompareText來執行區域識別比較。
  3. 如果我們遇到兩個姓氏相同的姓名,那麼我們對名字的其餘部分進行二級比較。
0

你可以通過你的StringList的每個項目迭代(可以稱之爲FullNames), 分割每個字符串,並把「分裂」兩個新的獨立的stringlists,你可以調用 FirstNameList和LastNameList。

現在創建第三個字符串列表,您可以調用ReverseFirstLast, 並將LastNameList中的項目與FirstNameList合併,並將它們放入ReverseNames中。

現在您的所有名稱都按相反順序排列。姓氏第一,名字最後。

您現在可以對ReverseFirstLast-list進行排序,並再次執行拆分&組合方法以再次反轉訂單並維護排序。

這是一種方法來完成並運行一個粗略的方法。

+2

那麼,它可以這樣做。但那會很弱。自定義比較功能是要走的路 – 2014-09-24 11:59:03

3

你可以使用的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進行排序,並將結果顯示在屏幕上。

相關問題