При работе с коллекциями в Object Pascal (Delphi) часто возникает задача поиска элемента по определенному свойству. В случае использования обобщенного списка TList<T> поиск может быть не таким очевидным, как в традиционных структурах данных. В этой статье мы рассмотрим, как можно эффективно осуществлять поиск в списке TList<T> по свойству, не создавая при этом экземпляры объектов.
Проблема
Допустим, у нас есть коллекция TList<TActivityCategory>, где TActivityCategory имеет свойство Name типа string. Нам необходимо выполнить поиск в этом списке по значению свойства Name, не создавая при этом экземпляры объектов TActivityCategory.
Решение
Для решения этой задачи можно использовать кастомный компаратор. При создании списка TList<T> можно передать компаратор, который будет сравнивать элементы списка на основе нужного свойства. В случае с TActivityCategory это будет сравнение строк.
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));
// Дальнейшие операции с коллекцией
end;
Такой подход позволяет использовать методы Contains и IndexOf для поиска элементов в списке, не создавая экземпляры объектов.
Альтернативные подходы
Если необходимо избежать создания кастомного компаратора, можно использовать простой линейный поиск по списку:
type
TActivityCategoryList = class(TList<TActivityCategory>)
public
function FindByName(const Name: string): Integer;
end;
function TActivityCategoryList.FindByName(const Name: string): Integer;
begin
for Result := 0 to Count-1 do
if Self[Result].Name = Name then
exit(Result);
Result := -1;
end;
Также можно рассмотреть использование TDictionary, которое позволит быстро осуществлять поиск по ключу, но это потребует дополнительной синхронизации данных в двух структурах.
Заключение
В зависимости от конкретной задачи и объема данных, можно выбрать наиболее подходящий способ поиска в списке TList<T>. Использование кастомного компаратора позволяет использовать встроенные функции поиска, тогда как линейный поиск или использование TDictionary могут быть более удобными и быстрыми в определенных ситуациях.
Обсуждение эффективного поиска в обобщенном списке TList по свойству без создания новых экземпляров объектов в Object Pascal (Delphi), с использованием кастомного компаратора и альтернативных подходов.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.