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;

如何在我的活动类中实现对每个字符串的搜索?

4

2 回答 2

6

在您的位置,我将编写 TObjectList 的子类并添加一个自定义 Search 方法,如下所示:

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>类型在 中声明SysUtils,因此请务必将其添加到您的 uses 子句中。

我相信这是我们在 Delphi 中最接近 lambda 表达式的方法。

于 2013-07-18T19:21:30.193 回答
3

TList 支持使用线性或二进制搜索来搜索项目。对于二分搜索,该算法假定一个排序。这不适合您的需求。在我看来,线性搜索是您所需要的,它可以通过 Contains 方法获得。

问题是 Contains 假定您正在搜索 T 的整个实例。您想将单个字符串传递给 Contains,但它不会接受。在你的情况下,它需要一个完整的记录。

您可以提供只比较单个字段的比较器。然后通过包含仅指定一个字段的记录。但这很丑陋。坦率地说,这个类的设计在搜索和排序方面非常薄弱。在我看来,比较器是状态变量而不是参数这一事实是一个令人震惊的失误。

底线是 TList 不会轻易地提供你正在寻找的东西而不诉诸丑陋。您可能应该在列表中实现一个老式循环来查找您的匹配项。

请注意,我假设您要提供单个字符串并搜索具有与该字符串匹配的字段的条目。如果实际上您确实想提供完整的记录并匹配每个字段,那么 Contains 可以满足您的需要,并使用合适的 Comparer 使用字典顺序。

于 2013-07-18T18:49:00.297 回答