Динамический TList TList - PullRequest
0 голосов
/ 16 февраля 2012

У меня есть такая проблема: как я могу добавить список в один список? Я пытался так, но основной список всегда возвращает один список, и не понимаю, где я ошибаюсь. Структура такая:

  PCombArray = array of Integer;
  PStatsRecord = record
    Comb: PCombArray;
    Freq: Integer;
  end;
  PStatsList = TList<PStatsRecord>;
  TStatsList = TList<PStatsList>;

Где Comb - это поле, которое работает как первичный ключ. Но тут все ок. я определяю основной список как:

var
  MainList: TStatsList;
  MySubList: PStatsList;

и создайте его без проблем. Процедура работы для заполнения подсписка; например, я называю эту процедуру MakeSubList и назначаю MySubList список, который был создан, а затем добавляю его в основной список:

  MainList := TList<PStatsList>.Create;
  try
    MainList.Clear;    
    for index := 1 to N do // generate N subList
    begin  
      ...
      MySubList := MakeSubList(index); // contain correct sub list, no problem here
      ...
      MainList.Add(MySubList);  // add mysublist to mainlist
    end;
    writeln (mainList.count);  // return 1, and not N-1 sublist
  finally
    MainList.Free;
  end; 

Спасибо, кто помогает мне понять, чтобы я мог решить это. Еще раз спасибо.

Ответы [ 3 ]

3 голосов
/ 16 февраля 2012

MainList - это список PStatsList, поэтому вам, безусловно, разрешено добавлять в него экземпляры PStatsList. Если бы вам не разрешили, ваш код вообще не скомпилировался бы или не запустился.

Если цикл выполняется N раз, то MainList.Add будет вызываться N раз, а MainList.Count будет N. Итак, если WriteLn(MainList.Count) печатает 1, то мы можем только заключить, что N = 1.

TList допускает дублирование, поэтому, даже если MakeSubList каждый раз возвращает один и тот же объект, он все равно может быть добавлен в основной список несколько раз.

1 голос
/ 16 февраля 2012

Ваша функция создания подсписка может быть неправильной, или вы могли спутать себя с вашими соглашениями об именах, которые никоим образом не следовали обычным соглашениям об именах Delphi / Pascal для типов.хотя.

Обратите внимание, что TList - это объект, поэтому, если вы хотите создать список TList, обязательно используйте TObjectList вместо обычного TList, если вам не нравятся утечки памяти.Ваш внутренний список относится к типу записи и не обязательно должен быть TObjectList, но если вы изменили StatsRecord на TStatsData как тип TObject (class), вам также следует изменить на TObjectList.

unit aUnit5;

interface

uses Generics.Collections;

procedure Test;

implementation

type
      CombArray = array of Integer;
      StatsRecord = record
        Comb: CombArray;
        Freq: Integer;
      end;
      TStatsList2 = TList<StatsRecord>;
      TStatsList = TObjectList<TStatsList2>;

var
      MainList: TStatsList;
      MySubList: TStatsList2;
      index:Integer;

procedure Test;
begin

      MainList := TStatsList.Create;
      try
        for index := 1 to 10 do // generate N subList
        begin
          MySubList := TStatsList2.Create;
          MainList.Add(MySubList);  // add mysublist to mainlist
        end;
        finally
        MainList.Free;
      end;
end;


end.
0 голосов
/ 19 мая 2012

    ..
    implementation
    type
      S64 = string[64];
      art_ptr = ^art_rec;
      art_rec = record
        sDes: S64;
        rCost: real;
        iQty: integer;
      end;
      art_file = file of art_rec;
    var
      lCatalog: TList;

    procedure disp_all;
    var
      lArt: TList;
      pA: art_ptr;
      c, 
      a: integer;
    begin
      for c:= 0 to lCatalog.Count -1 do begin
        lArt:= lCatalog[c];
        for a:= 0 to lArt.Count -1 do begin
          pA:= lArt[a];
          Dispose(pA);
        end;
        lArt.Clear;
        lArt.Free;
      end;
      lCatalog.Clear;
    end;//  disp_all

    procedure TfrmMain.FormCreate(Sender: TObject);
    begin
      lCatalog:= TList.Create;
    end;//  FormCreate

    procedure TfrmMain.FormDestroy(Sender: TObject);
    begin
      disp_all;
      lCatalog.Free;
    end;//  FormDestroy

    //  a normal BitButton click that adds 3 records to each art list (2)
    procedure TfrmMain.bbMCreate_Click(Sender: TObject);
    const
      nArt = 2;
      nRec = 3;
    var
      pA: art_ptr;
      lArt: TList;
      c: integer;
    begin
      // clears any previous added pointer record to art list that was added to the catalog
      disp_all;

      //  creates art lists and add 'em to the catalog list
      for c:= 0 to nArt -1 do begin
        lArt:= TList.Create;
        lCatalog.Add(lArt);

        //  creates records and add 'em to the art list
        for a:= 0 to nArt -1 do begin
          pA:= New(art_ptr);
          with pA^ do begin
            sDes:= Format('cat%d-art%d', [c, a]);
            rCost:= (c+1) * (a +1) *1.0;
            iQty:= (c+1) *10 + (a +1);
          end;
          lArt.Add(pA);
        end;
      end;
    end;//  bbMCreate_Click

    //  a normal BitButton click that reads 1 record from 1 art list
    procedure TfrmMain.bbMRead_Click(Sender: TObject);
    const
      c = 1;
      a = 2;
    var
      pA: art_ptr;
      lArt: TList;
    begin
      // gets art list #2 from catalog (index is 0 based. c=1)
      lArt:= lCatalog[c];
      // gets record #3 from art list (index is 0 based. a=2)
      pA:= lArt[a];
      // displays the record in a string grid called sgArt... at row a+1
      with sgArt, pA^ do begin
        // col 0 contains cat index and art index, can be useful...
        cells[0,a+1]:= Format('\%d\%d', [c,a]);
        cells[1,a+1]:= sDes;
        cells[2,a+1]:= FormatFloat('0.00', rCost);
        cells[3,a+1]:= IntToStr(iQty);
      end;
    end;//  bbMRead_Click
    
...