Search code examples
delphigenericstlist

How do I search a generic TList<T> collection?


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

I have a collection of

TList<TActivityCategory>

TActivityCategory has a Name property of type string and I want to search the TList using the Name property.

I see BinarySearch in the TList<> but that would require an instance of TActivityCategory. I just want to pass the string for a name.

How would I go about doing this?


Solution

  • When you create the list you can pass in a comparer. There are some comparer classes in the Generics.Defaults unit where you can pass in some anonymous method to compare two elements. They are used for several methods like IndexOf, Contains or Sort.

    Example:

    uses
      Generics.Defaults,
      Generics.Collections;
    
    type
      TActivityCategory = class
      private
        FName: string;
      public
        constructor Create(const Name: string);
        property Name: string read FName write FName;
      end;
    
    constructor TActivityCategory.Create(const Name: string);
    begin
      FName := Name;
    end;
    
    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));
    
      activities.Add(TActivityCategory.Create('Category B'));
      activities.Add(TActivityCategory.Create('Category C'));
      activities.Add(TActivityCategory.Create('Category A'));
    
      search := TActivityCategory.Create('Category C');
      if activities.Contains(search) then
        ShowMessage('found');
    
      ShowMessageFmt('Index: %d', [activities.IndexOf(search)]);
      activities.Sort;
      ShowMessageFmt('Index: %d', [activities.IndexOf(search)]);
    
    
      search.Name := 'Category D';
      if not activities.Contains(search) then
        ShowMessage('not found');
    
      search.Free;
      activities.Free;
    end;