Initialisation du tableau Delphi

j'ai actuellement, et elle suce:

type TpointArray = array [0..3] of Tpoint;

class function rotationTable.offsets(pType, rotState, dir: integer): TpointArray;
begin

  Result[0] := point(1, 1);
  Result[1] := point(1, 2);
  Result[2] := point(1, 1);
  Result[3] := point(1, 1);
end;

mais au lieu de cela, je veux faire quelque chose comme ceci:

class function rotationTable.offsets(pType, rotState, dir: integer): TpointArray;
begin
   Result := [Point(1,1), Point(1,2), Point(1,1), Point(1,1)];
end;

cependant, lors de la compilation, il se plaint que la syntaxe [1, 2, 3, 4] ne peut fonctionner que pour des entiers.

Est-il possible d'instancier/initialiser un tableau de Tpoint de la même manière que je veux?

16
demandé sur Alex O 2010-02-20 06:24:12

3 réponses

les tableaux d'enregistrements peuvent être intialisés dans les expressions const:

const
  Points : TPointArray = ((X: 1; Y: 1), (X:1; Y:2), (X:1; Y:1), (X:1; Y:1));

class function rotationTable.offsets(pType, rotState, dir: integer): TpointArray;
begin
   Result := Points;
end;

Dans XE7 il est possible de remplir un tableau dynamique d'enregistrements comme ceci:

function GetPointArray: TArray<TPoint>;
begin
  Result := [Point(1,1),Point(1,2),Point(1,1),Point(1,1)];
end;
22
répondu Gerry Coll 2015-03-31 05:54:38

la réponse de Plainth démontre le constructeur syntaxe tableaux dynamiques. Vous pouvez l'utiliser directement sur un tableau TPoint pour obtenir une fonction d'aide beaucoup plus simple:

type
  TPointDynArray = array of TPoint;
  T4PointArray = array[0..3] of TPoint;

function PointDynArrayTo4PointArray(const input: TPointDynArray): T4PointArray;
var
  i: Integer;
begin
  Assert(Length(input) = Length(Result));
  for i := 0 to High(input) do
    Result[i] := input[i];
end;

class function rotationTable.offsets(pType, rotState, dir: integer): T4PointArray;
begin
  // New dynamic-array-constructor syntax here
  Result := PointDynArrayTo4PointArray(TPointDynArray.Create(
    Point(1,1), Point(1,2), Point(1,1), Point(1,1)));
end;

Mais c'est exagéré. Delphi vous permet aussi de définir ouvrir tableaux en ligne, et il n'y a pas d'appel de constructeur supplémentaire à écrire. Le résultat utilise la syntaxe originale proposée, mais avec le tableau enveloppé dans un appel de fonction. Il fonctionnera dans tous les Delphes alors que la syntaxe" créer " ci-dessus est assez nouvelle.

function PointOpenArrayTo4PointArray(const input: array of TPoint): T4PointArray;
var
  i: Integer;
begin
  Assert(Length(input) = Length(Result));
  for i := 0 to High(input) do
    Result[i] := input[i];
end;

class function rotationTable.offsets(pType, rotState, dir: integer): T4PointArray;
begin
  Result := PointOpenArrayTo4PointArray(
    [Point(1,1), Point(1,2), Point(1,1), Point(1,1)]);
end;

Vous pouvez envisager d'utiliser réponse de Gerry juste pour donner à vos tableaux de points des noms significatifs, ce qui pourrait aider lors du débogage et l'un des huit nombres magiques dans ces définitions de points est erroné.


enfin, une note sur ce que Delphi voulait dire quand il disait "la syntaxe [1, 2, 3, 4] ne peut fonctionner que pour des entiers."Cette syntaxe définit un set, pas un tableau. Vous ne pouvez pas avoir un ensemble de valeurs d'enregistrement, mais vous disposer d'un ensemble d'entiers. Un effet secondaire est que la syntaxe pour un ensemble d'entiers est la même que la syntaxe pour un tableau d'entiers. Je pense que Delphi utilise le contexte pour lequel vous voulez dire, mais il peut parfois deviner tort.

8
répondu Rob Kennedy 2017-05-23 12:00:31

vous ne pouvez pas parce que vous ne pouvez pas exprimer dans le corps du code un point dans la façon dont vous pouvez l'exprimer dans le const section.

Cependant, vous pouvez faire quelques trucs afin d'avoir la vie plus facile, surtout si vous avez un nombre raisonnable de points.

vous pouvez implémenter une procédure simple comme celle-ci (code non testé):

procedure BlendDimensions(aXArray, aYArray: TIntegerDynArray; var aResult: TPointArray);
var
  nCount: integer;
  i: integer;

begin
  nCount:=High(aXArray);
  if nCount <> High(aYArray) then 
    Exception.Create('The two dimension arrays must have the same number of elements!');

  SetLength(aResult, nCount);
  for i:=0 to nCount do
  begin
    aResult[i].X:=aXArray[i]; //simple copy
    aResult[i].y:=aYArray[i];
  end;
end;

...où TIntegerDynArray est le tableau dynamique des entiers de la RTL. (En fait, il fonctionne avec n'importe quel tableau dynamique). En outre, TPointArray dans l'exemple ci-dessus est également dynamique.

Donc, pour faire votre travail, vous pouvez le faire comme ceci:

procedure Foo;
var
  myXCoords, myYCoords: TIntegerDynArray; //temp arrays
  myPoints: TPointArray; //this is the real thing

begin
  myXCoords:=TIntegerDynArray.Create( 1, 2, 3, 4, 5, 6, 7, 8, 9,10);
  myYCoords:=TIntegerDynArray.Create(21,32,34,44,55,66,65,77,88,92); //...for example 
  BlendDimensions(myXCoords, myYCoords, myPoints); //build the real thing
 //use it...
end;

remarques:

  • Vous voir clairement quels sont vos points
  • Vous pouvez très productifs de cette façon
  • Vous pouvez utiliser BlendDimensions également sur d'autres choses, pas seulement sur celui-ci
  • Vous pouvez facilement étendre BlendDimensions pour 3 (ou plus) dimensions
  • ...mais méfiez-vous car une copie est impliqué. :- ) Avec Aujourd'hui PCs, le point faible sera, de loin, votre main. :-) Vous obtiendrez fatigué de taper beaucoup plus vite jusqu'à l'heure de copie sera encore remarqué.

HTH

4
répondu John Thomas 2010-02-20 07:46:30