2013-07-18 47 views
2

我在修改從GENERIC SEARCH 作爲我的階級是更復雜的解決方案中號麻煩的理解,我需要創建多個不同的搜索功能搜索泛型列表

procedure TForm1.Button1Click(Sender: TObject); 
var 
    activities: TList<TActivityCategory>; 
    search: TActivityCategory; 
begin 
    activities := TObjectList<TActivityCategory>.Create(
    TDelegatedComparer<TActivityCategory>.Create(
    function(const Left, Right: TActivityCategory): Integer 
     begin 
     Result := CompareText(Left.Name, Right.Name); 
     end)); 

    ..... 

假設我TActivityCategory看起來像

TActivityCategory = class 
    FirstName : String; 
    Secondname : String; 
    onemore ..... 
    end; 

如何實現對我的活動類中每個字符串的搜索?

+0

比較器用於搜索以及排序 –

+0

@DavidHeffernan:我看到了(從你的答案)。謝謝;我沒有看到這種用法。我刪除了我的評論。 –

+1

您是否嘗試過其他更高級的容器庫,如http://spring4d.org或http://code.google.com/p/delphi-coll?有機會,你已經可以找到你需要的東西。或者,也許可以採用一些非通用庫,如「Delphi Inspirations」或「JCL」,並且 - 如果找到您需要的 - 在其上創建一個通用包裝? –

回答

6

在你的地方,我會寫TObjectList的子類,並補充說,應該是這樣一個自定義的搜索方法:

TSearchableObjectList<T:class> = class(TObjectList<T>) 
public 
    function Search(aFound: TPredicate<T>): T; 
end; 

這個方法的實現是

function TSearchableObjectList<T>.Search(aFound: TPredicate<T>): T; 
var 
    item: T; 
begin 
    for item in Self do 
    if aFound(item) then 
     Exit(item); 
    Result := nil; 
end; 

這樣的例子方法是

var 
    myList: TSearchableObjectList<TActivitycategory>; 
    item: TActivitycategory; 
    searchKey: string; 
begin 
    myList := TSearchableObjectList<TActivitycategory>.Create; 
    // Here you load your list 
    searchKey := 'WantedName'; 
    // Let´s make it more interesting and perform a case insensitive search, 
    // by comparing with SameText() instead the equality operator 
    item := myList.Search(function(aItem : TActivitycategory): boolean begin 
      Result := SameText(aItem.FirstName, searchKey); 
      end); 
    // the rest of your code 
end; 

上面使用的TPredicate<T>類型是declar編輯在SysUtils,所以一定要將它添加到您的使用條款。

我相信這是最接近我們可以在德爾福達到lambda表達式。

+0

我是否需要編寫一個實現函數Search(aFound:TPredicate ):T;我想我必須寫一些代碼,這個搜索是什麼意思? – Franz

+0

@Franz:不確定你的意思。我在其聲明下面添加了Search方法的實現。 – AlexSC

+0

@Franz:在最後兩個代碼塊中發佈的代碼(實現和示例)就在那裏。 –

3

TList支持使用線性搜索或二分搜索搜索項目。使用二分搜索,該算法假定排序。這不適合您的需求。線性搜索在我看來就是你所需要的,並且它可以通過Contains方法獲得。

問題是Contains假定您正在搜索T的整個實例。您想要將單個字符串傳遞給Contains,但它不會接受該字符串。它想要一個完整的記錄,在你的情況。

您可以提供只比較單個字段的比較器。然後傳遞只包含一個指定的字段的記錄。但這很醜陋。坦率地說,這個類的設計在搜索和排序時非常薄弱。在我看來,比較器是一個狀態變量而不是參數的事實是令人震驚的失誤。

底線是,TList不輕易提供你正在尋找的東西而不訴諸於醜。你可能應該在列表中實現一個老式的循環來尋找你的匹配。

請注意,我假設您想提供一個字符串並搜索具有匹配該字符串的字段的條目。如果實際上您確實希望提供完整的記錄並匹配每個字段,則Contains會根據您的需要進行操作,並使用適當的Comparer並使用字典順序。