私はのコレクションを持っています
TList<TActivityCategory>
TActivityCategory には文字列型の Name プロパティがあり、Name プロパティを使用して TList を検索したいと考えています。
TList<> に BinarySearch が表示されますが、これには TActivityCategory のインスタンスが必要です。名前の文字列を渡したいだけです。
どうすればこれを行うことができますか?
私はのコレクションを持っています
TList<TActivityCategory>
TActivityCategory には文字列型の Name プロパティがあり、Name プロパティを使用して TList を検索したいと考えています。
TList<> に BinarySearch が表示されますが、これには TActivityCategory のインスタンスが必要です。名前の文字列を渡したいだけです。
どうすればこれを行うことができますか?
リストを作成するときに、比較ツールに渡すことができます。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;
率直に言って、比較基準ベースのアプローチに必要なボイラープレートをすべて考慮すると、独自の検索ルーチンを作成するのが最も簡単かもしれません。
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;
検索するインスタンスがない場合は、独自の検索を行う必要があります。これを行うには、次の 3 つの基本的な方法があります。
TDictionary<string, TActivityCategory>
リストの横にa を維持します。検索は必要ありませんが、2 つの同期を維持するためにいくつかのコードを記述する必要があります。