10

重複の可能性:
特定のフィールド値を持つレコードのジェネリック TList を検索するにはどうすればよいですか?

私はのコレクションを持っています

TList<TActivityCategory>

TActivityCategory には文字列型の Name プロパティがあり、Name プロパティを使用して TList を検索したいと考えています。

TList<> に BinarySearch が表示されますが、これには TActivityCategory のインスタンスが必要です。名前の文字列を渡したいだけです。

どうすればこれを行うことができますか?

4

3 に答える 3

5

リストを作成するときに、比較ツールに渡すことができます。Generics.Defaultsユニットには、いくつかの匿名メソッドを渡して2つの要素を比較できるいくつかの比較クラスがあります。これらは、IndexOf、Contains、Sortなどのいくつかのメソッドに使用されます。

例:

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;
于 2011-11-08T19:05:12.383 に答える
2

率直に言って、比較基準ベースのアプローチに必要なボイラープレートをすべて考慮すると、独自の検索ルーチンを作成するのが最も簡単かもしれません。

type
  TActivityCategoryList = class(TList<TActivityCategory>)
  public
    function Find(const Name: string): Integer;
  end;

function TActivityCategoryList.Find(const Name: string): Integer;
begin
  for Result := 0 to Count-1 do
    if Self[Result].Name=Name then
      exit;
  Result := -1;
end;
于 2011-11-08T19:54:55.733 に答える
1

検索するインスタンスがない場合は、独自の検索を行う必要があります。これを行うには、次の 3 つの基本的な方法があります。

  • 二分探索:独自の二分探索を実装します。これは、リストがソートされている場合にのみ機能します。
  • 線形検索:独自の線形検索を実装します。これは常に機能しますが、大きなリストでは二分探索よりも大幅に遅くなります。
  • 辞書検索:TDictionary<string, TActivityCategory>リストの横にa を維持します。検索は必要ありませんが、2 つの同期を維持するためにいくつかのコードを記述する必要があります。
于 2011-11-08T17:32:57.980 に答える