'Is there way of copying the whole array into another array? (Other than using a For-loop)
Solution 1:[1]
For dynamic arrays:
var A,B: array of Byte;
begin
SetLength(A, <size>);
//initialize A
B:= A;
SetLength(B,Length(A));
end;
In dynamic arrays, the assignment statement duplicates only the reference to the array, while SetLength does the job of physically copying/duplicating it, leaving two separate, independent dynamic arrays.
Solution 2:[2]
See article on delphibasics.co.uk
You can copy an array using Copy method (pass in 0 for the index and Length(Source) as count to copy the full contents).
Do NOT use Move or CopyMemory for arrays of string/array/interface/etc managed types. Doing so will bypass Delphi's ref-counting mechanics and will result in memory leaks and corrupted data.
Solution 3:[3]
1- If your array doesn't contain any string or dynamic array, you can use move, but dynamic arrays are not to be handled like fixed-sized arrays:
var A,B: array[0..10] of integer;
DA, DB: array of double;
i: integer;
begin
for i := low(A) to high(A) do
A[i] := i;
move(A[0],B[0],length(A)*sizeof(A[0])); // first version, compiler does the stuff
move(A[0],B[0],sizeof(A)); // it works
move(A[0],B[0],40); // if you know what you're doing, since sizeof(A)=40
SetLength(DA,10); // DA[0]..DA[9]
for i := 0 to high(DA) do // or for i := 0 to 9 if you know what you're doing
DA[i] :=
SetLength(DB,length(DA));
if length(DA)<=length(DB) then // if your dynamic array may be void, use this before to avoid GPF
move(DA[0],DB[0],length(DA)*sizeof(DA[0]));
if pointer(DA)<>nil then // this will just check that DA[] is not void
move(pointer(DA)^,pointer(DB)^,length(DA)*sizeof(double)); // similar to previous
end;
2- If your array contains strings or other reference content array, you have to use a loop:
var A,B: array[0..10] of string;
i: integer;
begin
for i := 0 to high(A) do
A[i] := IntToStr(i);
for i := 0 to high(A) do
B[i] := A[i]; // this doesn't copy the string content, just add a reference count to every A[], and copy a pointer: it's very fast indeed.
end;
Solution 4:[4]
You can use a record type that uses a generic function to copy arrays to a dynamic TArray variable, which I have started using:
TGen = record // Unused record to allow generic functions.
public
...
class function arrayCopy<T>(const a: array of T): TArray<T>; static;
end;
class function TGen.arrayCopy<T>(const a: array of T): TArray<T>;
var i: integer;
begin
SetLength(result, length(a));
for i := Low(a) to High(a) do
result[i] := a[i];
end;
Given a form variable
dtls: TArray<TGridSetupDetails>;
and a parameter assigned from an array over an enumerated type
const adtls: array of TGridSetupDetails
you can initialize the form variable:
dtls := TGen.arrayCopy<TGridSetupDetails>(adtls);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Alexander Patalenski |
| Solution 2 | alex |
| Solution 3 | Server Overflow |
| Solution 4 | Mark Patterson |
