加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 如何在TList中存储动态数组?

发布时间:2020-12-15 04:22:22 所属栏目:大数据 来源:网络整理
导读:我需要存储未知数量的组.每个组都有未知数量的元素/项目. 这是我的’小组’: TGroup= array of Integer; ------ dynamic array (as you can see) :) 我想用TList来保持我的团队.我的想法是,我可能希望稍后访问这些组并向其添加更多项目. 我有这个代码,但我
我需要存储未知数量的组.每个组都有未知数量的元素/项目.
这是我的’小组’:
TGroup= array of Integer;     <------ dynamic array (as you can see) :)

我想用TList来保持我的团队.我的想法是,我可能希望稍后访问这些组并向其添加更多项目.

我有这个代码,但我不能让它工作:

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;

注意:代码已完成.您可以将其粘贴到Delphi(7)中进行试用.

解决方法

我已经创建了一个围绕动态数组RTTI的包装器.

这只是初稿,但它的灵感来自你的问题,以及TList方法缺失的事实.

type
  TGroup: array of integer;

var 
  Group: TGroup;
  GroupA: TDynArray;
  i,v: integer;
begin
  GroupA.Init(TypeInfo(TGroup),Group); // associate GroupA with Group
  for i := 0 to 1000 do begin
    v := i+1000; // need argument passed as a const variable
    GroupA.Add(v);
  end;
  v := 1500;
  if GroupA.IndexOf(v)<0 then // search by content
    ShowMessage('Error: 1500 not found!');
  for i := GroupA.Count-1 downto 0 do
    if i and 3=0 then
      GroupA.Delete(i); // delete integer at index i
end;

这个TDynArray包装器也可以用于字符串数组或记录数组…记录只需要打包并且只有引用计数字段(byte,integer,double …)或字符串引用计数字段(没有变量也没有接口内).

IndexOf()方法将按内容进行搜索.那是例如对于记录数组,所有记录字段(包括字符串)必须匹配.

请参阅源代码存储库中的the SynCommons.pas unit中的TDynArray.适用于Delphi 6到XE,并处理Unicode字符串.

TTestLowLevelCommon._TDynArray方法是与此包装器关联的自动单一测试.您将在此处找到记录数组和更高级功能的示例.

我目前正在实现SaveToStream和LoadToStream方法……

也许是在所有Delphi版本中使用类通用特性的新方法.

编辑:

我在TDynArray记录/对象中添加了一些新方法:

>现在,您可以将动态数组内容保存到字符串或从字符串加载(使用LoadFromStream / SaveToStream或LoadFrom / SaveTo方法) – 它将使用专有但非常快速的二进制流布局;
>并且您可以通过两种方式对动态数组内容进行排序:就地(即交换数组元素内容)或通过外部整数索引查找数组(使用CreateOrderedIndex方法 – 在这种情况下,您可以有几个订单到同一数据);
>您可以指定任何自定义比较函数,并且有一个新的Find方法可以使用快速二进制搜索(如果可用).

以下是这些新方法的工作原理:

var
  Test: RawByteString;
...
  Test := GroupA.SaveTo;
  GroupA.Clear;
  GroupA.LoadFrom(Test);
  GroupA.Compare := SortDynArrayInteger;
  GroupA.Sort;
  for i := 1 to GroupA.Count-1 do
    if Group[i]<Group[i-1] then
      ShowMessage('Error: unsorted!');
  v := 1500;
  if GroupA.Find(v)<0 then // fast binary search
    ShowMessage('Error: 1500 not found!');

更接近通用范例,更快,对于Delphi 6到XE …

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读