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?
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;
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.
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