如何在通用 TList 中搜索具有特定字段值的记录? [英] How can I search a generic TList for a record with a certain field value?

查看:20
本文介绍了如何在通用 TList 中搜索具有特定字段值的记录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Everything about generic TList. I have this structure:

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>;

主要列表是 TExtrList 并且在这个列表中我有所有日期和日期所有轮子的日期.我想搜索日期是否存在.如果不存在,我将在 Extract from TEstr 的子列表 TExtractList 中添加信息.当我从 TEstrList 搜索时,Delphi 会询问我关于 TEstr 类型的信息.我只需要搜索 Date.那么如何在通用 TList 中搜索单个字段?

The main list is TExtrList and in this list I have all dates and for date all wheel with that date. I want to search if a date exists or not. If not exist I add in sublist TExtractList of Extract from TEstr the info. When I search from TExtrList Delphi asks me about TEstr type. I need to search for Date only. So how can I search for single field in a generic TList?

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

PS: I have deleted last post because here I have tried to explain better.

推荐答案

我们又来了.

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

You should use the built-in TList<T>.BinarySearch() function, even if it rightfully asks for a TEstr record as a parameter. You'll first need to use TList<T>.Sort() to sort the list using the same criteria as for the search, then call BinarySearch() to find your record.

这是一个同时执行(排序和搜索)的函数:

Here's a function that does both (sort and search):

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;

BinarySearch 假定列表已排序(这是二分搜索的本质!).在您第一次调用时,您需要设置 Sort=True 以便正确排序列表.在随后的调用中,Sort 应该是 False.当然,在实际使用中,您可能有单独的搜索和排序例程,并且您可能将它们作为从 TList 降序的类的方法(使事情更容易).为了演示目的,我将它们放在同一个例程中.

BinarySearch assumes the list is sorted (that's the essence of binary searching!). On your first call you need to set Sort=True so the list is properly sorted. On subsequent calls Sort should be False. Of course, in actual use you'd probably have separate routines for searching and sorting, and you'd probably have them as methods of a class descending from TList<TEstr> (to make things easyer). I places both in the same routine for dempnstration purposes.

这篇关于如何在通用 TList 中搜索具有特定字段值的记录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆