'Is there way of copying the whole array into another array? (Other than using a For-loop)

Is there way of copying the whole array into another array? Other than using a for-loop.

Does the move or copy command work for this? I did try but it had an error: "Incompatible types".

Should I stick to the 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