How can I search a generic TList for a record with a certain field value?

前端 未结 5 1042
你的背包
你的背包 2020-12-17 02:47

Everything about generic TList. I have this structure:

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

           


        
5条回答
  •  暖寄归人
    2020-12-17 03:17

    Here we go again.

    You should use the built-in TList.BinarySearch() function, even if it rightfully asks for a TEstr record as a parameter. You'll first need to use TList.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): Integer;
    var Comparer: IComparer;
        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.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 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 (to make things easyer). I places both in the same routine for dempnstration purposes.

提交回复
热议问题