如何在通用TList中搜索具有特定字段值的记录?

Mar*_*ato 4 delphi generics search

关于通用的一切TList.我有这个结构:

Type
  TExtract = record
    Wheel: string;
    Extract: array [1..5] of Byte;
  end;

  TExtractList = TList<TExtract>

  TEstr = record
    Date: TDate;
    Extract: TExtractList;
  end;

  TEstrList = TList<TEstr>;
Run Code Online (Sandbox Code Playgroud)

主要列表是TExtrList在这个列表中我有所有日期和日期所有轮子与该日期.我想搜索是否存在日期.如果不存在,我TExtractListTEstr信息中添加Extract的子列表.当我从TExtrListDelphi 搜索关于TEstr类型的问题时.我只需要搜索Date.那么如何在通用中搜索单个字段TList

PS:我删除了上一篇文章,因为在这里我试图更好地解释.

Cos*_*und 8

再来一次.

您应该使用内置TList<T>.BinarySearch()函数,即使它正确地要求TEstr记录作为参数.您首先需要使用TList<T>.Sort()与搜索相同的条件对列表进行排序,然后调用BinarySearch()以查找记录.

这是一个兼具(排序和搜索)功能的函数:

uses Generics.Defaults; // this provides TDelegatedComparer
uses Math; // this provides Sign()

function SearchList(Date:TDate; Sort:Boolean; List:TList<TEstr>): Integer;
var Comparer: IComparer<TEstr>;
    Dummy: TEstr;
begin
  // Prepare a custom comparer that'll be used to sort the list
  // based on Date alone, and later to BinarySearch the list using
  // date alone.
  Comparer := TDelegatedComparer<TEstr>.Construct(
    function (const L, R: TEstr): Integer
    begin
      Result := Sign(L.Date - R.Date);
    end
  );

  // If the list is not sorted, sort it. We don't know if it's sorted or not,
  // so we rely on the "Sort" parameter
  if Sort then List.Sort(Comparer);

  // Prepare a Dummy TEstr record we'll use for searching
  Dummy.Date := Date;

  // Call BinarySearch() to look up the record based on Date alone
  if not List.BinarySearch(Dummy, Result, Comparer) then
    Result := -1;
end;
Run Code Online (Sandbox Code Playgroud)

BinarySearch假设列表已排序(这是二进制搜索的本质!).在第一次通话时,您需要设置Sort=True以便列表正确排序.在接下来的电话Sort应该是False.当然,在实际使用中,您可能有单独的搜索和排序例程,并且您可能将它们作为类的方法降序TList<TEstr>(使事情更容易).为了dempnstration的目的,我将它们放在同一个例程中.