Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.03.05;
Скачать: [xml.tar.bz2];

Вниз

аналог 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.013 c
2-1140001625
проходил мимо заглянул
2006-02-15 14:07
2006.03.05
StringGrid


3-1136982771
tytus
2006-01-11 15:32
2006.03.05
ХЕЛППП!!! BDEError Record/Key Deleted


15-1139816379
alexeis
2006-02-13 10:39
2006.03.05
отказ от IDE?


3-1137025928
Kromwerk
2006-01-12 03:32
2006.03.05
Преобразование времени


15-1139772246
Nick Denry
2006-02-12 22:24
2006.03.05
Подскажите компонент





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский