从块中的列表复制动态数组

时间:2012-02-23 10:17:27

标签: delphi delphi-xe2

在帖子中:Copy sublist from list留下来解释我,对于副本,列表中的子列表需要复制单个元素这样做:

for iIndex2 := 0 to MyList.Last.Count-1 do 
  MySubList.Add(MyList.Last[iIndex2]); 

我已经确认这种复制方法在列表中排名最高的方法需要花费很多时间,这也是一些矿工。尝试在相同条件下使用静态数组进行模拟我需要几毫秒,一次复制数组中的所有子列表而不是单个元素。 为了更好地解释,我有:

program Test_with_array_static;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, System.Generics.Collections;

type
  TMyArray = array [1..10] of Integer;
  TMyList = TList<TMyArray>;

var
  MyArray: TMyArray;
  MyList: TMyList;
  iIndex1, iIndex2: Integer;
begin
  try
    { TODO -oUser -cConsole Main : Insert code here }

    MyList := TList<TMyArray>.Create;
    try
      for iIndex1 := 1 to 10 do
      begin
        if MyList.Count <> 0 then MyArray := MyList.Last;
        MyArray[iIndex1] := iIndex1;
        MyList.Add(MyArray);
      end;

      for iIndex1 := 0 to Pred(MyList.Count) do
      begin
        for iIndex2 := 1 to 10 do Write(MyList[iIndex1][iIndex2]:3);
        Writeln;
      end;
    finally
      MyList.Free;
    end;

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

所以我认为不使用list作为子列表但是数组等工作,但在我的情况下,我一般不知道数组中的元素数量多少,需要动态数组。 我更改了代码:

program Test_with_array_dynamic;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, System.Generics.Collections;

type
  TMyArray = array of Integer;
  TMyList = TList<TMyArray>;

var
  MyArray: TMyArray;
  MyList: TMyList;
  iIndex1, iIndex2: Integer;
begin
  try
    { TODO -oUser -cConsole Main : Insert code here }

    MyList := TList<TMyArray>.Create;
    try
      SetLength(MyArray, 10);
      for iIndex1 := 1 to 10 do
      begin
        if MyList.Count <> 0 then MyArray := MyList.Last;
        MyArray[iIndex1] := iIndex1;
        MyList.Add(MyArray);
      end;

      for iIndex1 := 0 to Pred(MyList.Count) do
      begin
        for iIndex2 := 1 to 10 do Write(MyList[iIndex1][iIndex2]:3);
        Writeln;
      end;
    finally
      MyList.Free;
    end;

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

所以,我再次遇到了以前的问题;当然,改变这一行:

if MyList.Count <> 0 then MyArray := MyList.Last;

在复制单元素模式下,所有工作。 现在我问,如果真的不可能在一段时间内复制一个数组,而不对单个元素进行复制,我只需要速度问题。时间非常重要。 再次感谢所有可以解决这个问题的人。再次感谢。

2 个答案:

答案 0 :(得分:3)

您需要添加数组的副本。否则,由于您继续将数组变量的长度设置为相同的值,因此您最终会处理相同的单个动态数组。要制作数组的副本,只需在将其添加到列表之前调用Copy

MyList.Add(Copy(MyArray));

答案 1 :(得分:2)

如果我理解正确,你想复制内存以提高速度,这是一种方法:

type
  TMyArray = array of Integer;

procedure CopyMyArraytest;
var
  LSrcArray: TMyArray;
  LDestArray: TMyArray;
  Index: Integer;
begin
  // set the length, can be later changed
  SetLength(LSrcArray, 100);
  // fill the array
  for Index := Low(LSrcArray) to High(LSrcArray) do
    LSrcArray[index] := index;
  // prepare the length of destination array
  SetLength(LDestArray, Length(LSrcArray));
  // copy elements from source to dest, we need Length(LSrcArray) * SizeOf(Integer)
  // because Move needs the number of bytes, we are using "integer" so a simple
  // multiplication will do the job
  Move(LSrcArray[Low(LSrcArray)], LDestArray[Low(LDestArray)], Length(LSrcArray) * SizeOf(Integer));

  // compare elements, just to make sure everything is good
  for Index := Low(LSrcArray) to High(LSrcArray) do
    if LSrcArray[Index] <> LDestArray[Index] then begin
      ShowMessage('NOOO!!!');
      Exit;
    end;
  ShowMessage('All good');
end;