Аналог TStringList для записей

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Аналог TStringList для записей

Сообщение krab » 16.07.2010 17:00:56

Как лучше хранить набор записей? Нужен аналог StringList. Есть ли что-то с простым (ведущим к минимуму ошибок) интерфейсом, без ручной работы с указателями и т. п.?
То есть:
Код: Выделить всё
type
   TPerson = record
       Name, Telephone, Address : String;     
   end;

var
  Many_Persons : TRecordList;
  x, y : TPerson;

begin
  Many_Persons := TRecordList.Create(TPerson);

  x.Name := 'Holmes';
  x.Telephone := '1234567890';
  x.Address := '221b Baker Street London '

  Many_Persons.Add(x);

  y := Many_Persons[0];
end
krab
постоялец
 
Сообщения: 108
Зарегистрирован: 17.02.2010 18:23:08

Re: Аналог TStringList для записей

Сообщение А.Н. » 16.07.2010 17:12:27

TObjectList или TCollection?
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Аналог TStringList для записей

Сообщение hinst » 16.07.2010 18:42:23

шаблонный список. скачайте мой! viewtopic.php?f=41&t=5898
или в фпц тоже вот ещё есть TGList вроде...
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Аналог TStringList для записей

Сообщение А.Н. » 16.07.2010 21:48:13

А коллекция чем плоха?
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Аналог TStringList для записей

Сообщение krab » 16.07.2010 23:25:34

А.Н. писал(а):А коллекция чем плоха?

Код: Выделить всё
type
   // Forward declarations
   TMyCollectionItem=class;
   TMyCollection=class;


   TMyCollection=class(TCollection)
   private
      function GetItem(Index: Integer): TMyCollectionItem;
      procedure SetItem(Index: Integer; const Value: TMyCollectionItem);
   public
      Constructor Create;
      property Items[Index: Integer]: TMyCollectionItem read GetItem write SetItem; default;
   end;

   TMyCollectionItem=class(TCollectionItem)
   private
      FString:String;
      FBool: Boolean;
      FInt:integer;
      FObj:TSomeClass;
      Procedure SetObj(const Value: TSomeClass);
   public
      procedure Assign(Source:TPersistent);override;
      constructor Create(AOwner:TCollection);override;
      destructor destroy;override;
   published
      property BoolProp:Boolean read FBool write FBool;
      property StringProp:String read FString write FString;
      property IntProp:integer read FInt write FInt;
      property ObjProp: TSomeClass read FObj write SetObj;
   end;

{ TMyCollection }

constructor TMyCollection.Create;
begin
  inherited Create(TMyCollectionItem);
end;

function TMyCollection.GetItem(Index: Integer): TMyCollectionItem;
begin
  Result:=TMyCollectionItem(inherited GetItem(Index));
end;

procedure TMyCollection.SetItem(Index: Integer; const Value: TMyCollectionItem);
begin
  inherited SetItem(index,value);
end;

{ TMyCollectionItem }

procedure TMyCollectionItem.Assign(Source: TPersistent);
begin
  if Source is TMyCollectionItem then
     with Source as TMyCollectionItem do
  begin
     FString:=StringProp;
     FBool:=BoolProp;
     FInt:;=Intprop
         FObj.Assign(ObjProp);
  end
  else
     inherited Assign(source);
end;

constructor TMyCollectionItem.Create(AOwner: TCollection);
begin
  inherited Create(AOwner);
  FObj:=TSomeClass.Create(self);
end;

destructor TMyCollectionItem.destroy;
begin
  inherited;
  FObj.Free;
end;

procedure TMyCollectionItem. SetObj(const Value: TSomeClass);
begin
  FEntries.Assign(Value);
end;

И все это ради того, чтобы получить аналог:
Код: Выделить всё
struct TItem {
      std::string FString;
      bool Boolean;
      int integer;
      myobj SomeClass;
}
std::list<TItem> many;


Добавлено спустя 3 минуты 2 секунды:
У меня много разных записей, поэтому строки, что я привел для TCollection, можно смело умножать на 10... :shock:
krab
постоялец
 
Сообщения: 108
Зарегистрирован: 17.02.2010 18:23:08

Re: Аналог TStringList для записей

Сообщение alexs » 16.07.2010 23:49:09

krab писал(а):У меня много разных записей, поэтому строки, что я привел для TCollection, можно смело умножать на 10...

Вместо записи используем класс, и TList. Ничего объявлять дополнительно не надо. Заодно данные правильно будут оформленны. И проверки внутри объекта на допустимость данных размещать более правильно. А вот устройство хранения данных не обязанно знать, какие данные коректны для твоей записи.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Аналог TStringList для записей

Сообщение zub » 17.07.2010 00:15:00

/offtopic
hinst
а у шаблонов как со стабильностью и отладкой? у меня давно напрашивается шаблонизация, но както ссыкотно
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Аналог TStringList для записей

Сообщение А.Н. » 17.07.2010 08:47:06

krab писал(а):У меня много разных записей, поэтому строки, что я привел для TCollection, можно смело умножать на 10...

От TCollection наследовать, в общем-то, необязательно.
Только, как вы собираетесь делать Assign, используя какой-то там список? Т.е. запись должна быть не с public, а с published свойствами, и потребуется использовать RTTI? Тоже, при желании, возможно реализовать и для коллекции. Затем, использовать один потомок.
Только имеет ли смысл? Может, тогда, лучше сделать метод Assign в записи или, вообще, правильнее объекты использовать? Коллекция сама вызовет их Assign.

А так, достаточно переопределить только TCollectionItem. Что вы хотите не понимаю. Если у вас много типов записей, будет такое же число, только они станут потомками элемента коллекции.

Аналогичная ситуация с шаблонами. Всё-равно, вам придётся определять списки для всех типов. Если же вам не нужна проверка типов, вы можете использовать TObjectList. В чём проблема? Нужно изобрести велосипед?
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Аналог TStringList для записей

Сообщение hinst » 17.07.2010 11:19:01

@zub
ну я использовал шаблоны в нескольких своих проектах. вроде нормально. при исключении выдаётся и номер строки, и имя метода, и имя шаблона, и тип, по которому он специализируется, так что с отладкой вроде-бы нормально. некоторые хитрые конструкции пока не собираются или не линкуются, а так, обычные во время выполнения работают нормально. глюков не замечал.
@krab
ну вот шаблоны в таком случае для вас единственный вариант.
быстро,
просто,
не нужно много писать,
не нужно приводить типы,
аналогия с C++
остаётся только выбрать, какие использовать

P.S.: Под хитрыми конструкциями понимал наследование шаблонов. надеюсь, в будущих версиях FPC оно появится
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Аналог TStringList для записей

Сообщение alexs » 17.07.2010 11:35:54

hinst писал(а):аналогия с C++

Это главное? :D
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Аналог TStringList для записей

Сообщение А.Н. » 17.07.2010 11:42:07

@krab
ну вот шаблоны в таком случае для вас единственный вариант.
быстро,
просто,
не нужно много писать,
не нужно приводить типы,
аналогия с C++
остаётся только выбрать, какие использовать

"Быстро, качественно, недорого. Выберите любые два пункта."? ;)
Единственное, что плохо с коллекцией, - приведение типов. Много писать, в принципе, тоже не нужно.
Причём, также быстро и просто. Аналогия с C++ меня почему-то настораживает. :lol:
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Аналог TStringList для записей

Сообщение yurgel » 18.07.2010 18:16:06

krab писал(а):И все это ради того, чтобы получить аналог:
Код: Выделить всё
struct TItem {
      std::string FString;
      bool Boolean;
      int integer;
      myobj SomeClass;
}
std::list<TItem> many;


можно ещё короче: Records: array of array of Variant. чтобы не было путаницы, индексы первого массива выносите в константы, и тогда

Код: Выделить всё
  Name := Records [IDX_NAME, 20];


- это обращение к полю IDX_NAME в двадцатой (а точнее - в двадцать первой, т.к. у динамических массивов индексация идёт с нуля) строке aka записи.
yurgel
новенький
 
Сообщения: 37
Зарегистрирован: 29.06.2010 16:06:58

Re: Аналог TStringList для записей

Сообщение krab » 28.07.2010 18:04:58

krab
постоялец
 
Сообщения: 108
Зарегистрирован: 17.02.2010 18:23:08

Re: Аналог TStringList для записей

Сообщение VirtUX » 16.02.2014 16:43:36

Есть массив параметров типа record. Есть список строковых идентификаторов для этого массива параметров. Сейчас это выглядит в двух вариантах:
Первый:
Код: Выделить всё
PNodeString = ^NodeString;
NodeString = record
Next, Pred: PNodeString;
sID: string;
p: Pointer;
end;

Второй:
Код: Выделить всё
ArrNode = array of record
  sID: string;
  p: Pointer;
end;

В p: Pointer хранятся адреса на параметры в виде записей:
Код: Выделить всё
AnyParam = record
p1: AnyType;
...
pN: AnyType;
end;

где AnyType - это любой возможный тип данных.
Для первого варианта у меня уже написаны процедуры сортировки, поиска и т.п. по sID. Для второго все, что мне нужно есть в TStringList, но он не может хранить простые Pointer, а лишь обязательно TObject. Создавать целые объекты для миллионов параметров AnyParam мне кажется ресурсозатратным для ОЗУ.
Все параметры уникальны и не повторяются. Т.е. объектные методы типа Assign мне не нужны. Да и вообще никакие объектные методы мне, применительно к параметрам, не нужны!
Где бы взять такой TStringList, имеющий возможность хранить просто Pointer вместо TObject? Или как обмануть TStringList?
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Аналог TStringList для записей

Сообщение svk12 » 16.02.2014 17:59:20

Например:

Код: Выделить всё
type
TPointerStore =class
FPointer:Pointer;
end;


И вставляйте его в TStringList.
svk12
постоялец
 
Сообщения: 409
Зарегистрирован: 09.06.2008 18:42:47

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 234

Рейтинг@Mail.ru