问题描述
关于通用 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 中搜索具有特定字段值的记录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!