I need to store an unknown number of groups. Each group has an unknown number of elements/items.
This is my ‘group’:
TGroup= array of Integer; <------ dynamic array (as you can see) :)
I want to use a TList to hold my groups. The idea is that I may want to access the groups later and add more items to them.
I have this code, but I can’t make it work:
TYPE
TGroup= array of Integer; // Each group has x items (x can be from 1 to 10000)
procedure TForm1.FormCreate(Sender: TObject);
VAR CurGroup: TGroup;
grp, item: Integer;
Groups: TList; // can contain up to 1 million groups
begin
Groups:= TList.Create;
{ Init }
for grp:= 1 to 4 DO // Put a dummy item in TList
begin
SetLength(CurGroup, 1); // Create new group
Groups.Add(@CurGroup); // Store it
end;
CurGroup:= NIL; // Prepare for next use
for grp:= 1 to 4 DO // We create 4 groups. Each group has 3 items
begin
CurGroup:= Groups[Groups.Count-1]; // We retrieve the current group from list in order to add more items to it
{ We add few items }
for item:= 0 to 2 DO
begin
SetLength(CurGroup, Length(CurGroup)+1); // reserve space for each new item added
CurGroup[item]:= Item;
end;
Groups[Groups.Count-1]:= @CurGroup; // We put the group back into the list
end;
{ Verify }
CurGroup:= NIL;
CurGroup:= Groups[0];
Assert(Length(CurGroup)> 0); // FAIL
if (CurGroup[0]= 0)
AND (CurGroup[1]= 1)
AND (CurGroup[2]= 2)
then Application.ProcessMessages;
FreeAndNil(Groups);
end;
Note: The code is complete. You can paste it in your Delphi (7) to try it.
I’ve created a wrapper around dynamic array RTTI.
It’s just a first draft, but it was inspired by your question, and the fact that the
TListmethods are missing.This
TDynArraywrapper will work also with array of string or array of records… Records need only to be packed and have only not reference counted fields (byte, integer, double…) or string reference-counted fields (no Variant nor Interface within).The IndexOf() method will search by content. That is e.g. for an array of record, all record fields (including strings) must match.
See
TDynArrayin the SynCommons.pas unit from our Source Code repository. Works from Delphi 6 up to XE, and handle Unicode strings.And the
TTestLowLevelCommon._TDynArraymethod is the automated unitary tests associated with this wrapper. You’ll find out here samples of array of records and more advanced features.I’m currently implementing
SaveToStreamandLoadToStreammethods…Perhaps a new way of using generic-like features in all Delphi versions.
Edit:
I’ve added some new methods to the
TDynArrayrecord/object:LoadFromStream/SaveToStreamorLoadFrom/SaveTomethods) – it will use a proprietary but very fast binary stream layout;CreateOrderedIndexmethod – in this case, you can have several orders to the same data);Findmethod will can use fast binary search if available.Here is how those new methods work:
Still closer to the generic paradigm, faster, and for Delphi 6 up to XE…