Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.03.05;
Скачать: CL | DM;

Вниз

аналог TList с полем Data   Найти похожие ветки 

 
Piter ©   (2006-02-02 22:43) [0]

Есть ли стандартный аналог TList с дополнительным полем Data (Object) для каждой записи? Ну типа TStringList, только хранятся Pointer (integer) + доп. массив Pointer (Object).

И еше было бы супер, если там фильтрация была, то есть:

TObj.Filter := 72

И чтобы в каком-нибудь поле остался только массив записей, значение которых равно 72


 
Gero ©   (2006-02-02 22:45) [1]

> Есть ли стандартный аналог TList с дополнительным полем
> Data (Object) для каждой записи?

Зачем если у тебя каждая запись и так Object? Размещай в нем что хочешь, какие проблемы?

> И чтобы в каком-нибудь поле

Каком поле?


 
Джо ©   (2006-02-02 22:47) [2]

TList позволяет хранить ссылку на любые данные. Что мешает хранить в нем указатель на запись (record), в которой и хранить это "дополнительное поле"?


 
Piter ©   (2006-02-02 23:12) [3]

Неудобно фильтровать по значению поля, придется пробегать весь лист при каждом новом значении фильтра. Возможно, есть способы поэффективнее.


 
Lamer@fools.ua ©   (2006-02-02 23:14) [4]

>Возможно, есть способы поэффективнее.

Один точно есть: написать свой класс с необходимой функциональностью :-)


 
Gero ©   (2006-02-02 23:56) [5]

> придется пробегать весь лист при каждом новом значении фильтра

Да, а ты думаешь, скажем IndexOf как-то по-другому работает?
Я именно так всегда и делаю.


 
GuAV ©   (2006-02-03 00:24) [6]

Думаю, нужно наследоваться от TList, в нём перекрыть notify и добавить приватное поле - ещё один такой же наследник, чтобы они ссылались друг на друга. А в notify - синхронизировать их изменения.


 
Джо ©   (2006-02-03 03:11) [7]

А я бы сделал как-то так.

unit SmartLst;

interface
uses SysUtils, Classes, Contnrs;

type

 TSmartList = class
 private
   FList: TList;
   FFiltered: TObjectList;
   FFilter: Integer;
   procedure SetFilter(const Value: Integer);
   function GetCount: Integer;
   function GetObjects(Index: Integer): TObject;
   function GetItems(Index: Integer): Integer;
 public
   procedure Clear;
   constructor Create;
   destructor Destroy; override;
   procedure Add (Item: Integer; Data: TObject); overload;
   procedure Add (Item: Integer); overload;
   property Items[Index: Integer]: Integer read GetItems; default;
   property Objects[Index: Integer]: TObject read GetObjects;
   property Count: Integer read GetCount;
   property Filter: Integer read FFilter write SetFilter;
   property Filtered: TObjectList read FFiltered;
 end;

implementation

type
 TListItem = record
   Item: Integer;
   Data: TObject;
 end;

{ TSmartList }

procedure TSmartList.Add(Item: Integer; Data: TObject);
var
 NewItem: ^TListItem;
begin
 GetMem (NewItem,SizeOf(TListItem));
 NewItem^.Item := Item;
 NewItem^.Data := Data;
 FList.Add(NewItem);

 if (FFilter = 0) and (Item = 0) then
   FFiltered.Add(Data);
end;

procedure TSmartList.Add(Item: Integer);
begin
 Add (Item,nil)
end;

procedure TSmartList.Clear;
var
 I: Integer;
begin
 for I := 0 to FList.Count - 1 do
   FreeMem(FList[I]);

 FList.Clear
end;

constructor TSmartList.Create;
begin
 FList := TList.Create;
 FFiltered := TObjectList.Create(False);
end;

destructor TSmartList.Destroy;
begin
 FList.Free;
 FFiltered.Free;
 inherited;
end;

function TSmartList.GetCount: Integer;
begin
 Result := FList.Count
end;

function TSmartList.GetItems(Index: Integer): Integer;
begin
 Result := TListItem(FList[Index]^).Item
end;

function TSmartList.GetObjects(Index: Integer): TObject;
begin
 Result := TListItem(FList[Index]^).Data
end;

procedure TSmartList.SetFilter(const Value: Integer);
var
 I: Integer;
begin
 if Value = FFilter then
   Exit;

 FFiltered.Clear;

 FFilter := Value;
 for I := 0 to Count - 1 do
   if GetItems(I) = Value then
     FFiltered.Add(GetObjects(I))
end;

end.


И пользовался бы в таком духе:


procedure TForm18.Button1Click(Sender: TObject);
var
 I: Integer;
 SmartList: TSmartList;
begin
 SmartList := TSmartList.Create;
 try
   SmartList.Add(5,TButton.Create(Self));
   SmartList.Add(1,TLabel.Create(Self));
   SmartList.Add(0,TEdit.Create(Self));
   SmartList.Add(1,TListBox.Create(Self));
   SmartList.Add(3,TComboBox.Create(Self));

   // проверка фильтрации
   SmartList.Filter := 1;
   for I := 0 to SmartList.Filtered.Count - 1 do
     ShowMessage (SmartList.Filtered[I].ClassName);

   // проверка Items
   for I := 0 to SmartList.Count - 1 do
     ShowMessage (IntToStr(SmartList[I]));

   // проверка Objects
   for I := 0 to SmartList.Count - 1 do
     ShowMessage ((SmartList.Objects[I].ClassName));

 finally
   SmartList.Free;
 end;
end;


Если где-то закосячил, сорри, наспех состряпал.


 
аноним   (2006-02-03 07:59) [8]

Джо ©   (03.02.06 03:11) [7]
отличный пример! взял на заметку.


 
ЮЮ ©   (2006-02-03 08:02) [9]

Удалено модератором
Примечание: Offtopic


 
Джо ©   (2006-02-03 13:04) [10]


> [7] Джо ©  

1. В Destroy забыл вставить Clear.
2. В Add(Item: Integer; Data: TObject); убрать 2 последние строки, они остались от предыдущего варианта.


 
Джо ©   (2006-02-03 13:05) [11]

3. В Clear нужно, наверное, также делать FFiltered.Clear.



Страницы: 1 вся ветка

Текущий архив: 2006.03.05;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.058 c
15-1139415358
Хинт
2006-02-08 19:15
2006.03.05
Indy10 для Delphi7


3-1136985019
Term
2006-01-11 16:10
2006.03.05
Помогите с синтаксисом запроса UPDATE


1-1138529550
Wistler
2006-01-29 13:12
2006.03.05
Импорт функции из DLL


2-1139741086
ZeFiR
2006-02-12 13:44
2006.03.05
MDI приложение


2-1139929083
VanDet
2006-02-14 17:58
2006.03.05
Помогите мне решить еще одну задачу (Пожалуйста, Пожалуйста, Пож)