Reputation: 2281
in post: Copy sublist from list was stayed explained me that for copy a sublist in a list need copy single elements doing so:
for iIndex2 := 0 to MyList.Last.Count-1 do
MySubList.Add(MyList.Last[iIndex2]);
I have verified that this method of copy for elements much much highest in list take much time, in order too of some minetes. Trying to simulate with static array in same condition i take few miliseconds, copying all sublist in an array in one time and not for single element. Just for explain better, i have:
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.
So i have thinked to use not list as sublist but array and so work, but in my case i don't know in general how much are element in array and need dynamic array for it. I have changed code in:
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.
and so, i have again the problem of before; of course, changing this line:
if MyList.Count <> 0 then MyArray := MyList.Last;
in mode of copy single element, all work. Now i ask, if really not is possible copy an array in a time, without do a copy for single elements, i need it for question of speed only. And time is very much important. Thanks again very much to all that can solve me this problem. Thanks again.
Upvotes: 3
Views: 828
Reputation: 163347
You need to add a copy of the array. Otherwise, since you keep setting the array variable's length to the same value, you end up working on the same single dynamic array. To make a copy of an array, simply call Copy
prior to adding it to your list:
MyList.Add(Copy(MyArray));
Upvotes: 3
Reputation:
if I understand you correctly, you want to copy memory to improve speed, here's one way to do it:
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;
Upvotes: 2