使用 TArrays 的多维记录,如何在 Delphi 10.3 中设置长度
Multidimensional records with TArrays, how to set length in Delphi 10.3
我在尝试使用 TArrays 在数据结构中创建第三维时遇到问题。
如何设置 TSensorGroupSeries 中的长度? --> 下面示例中的 SetLength(fSensorValues, fNbrSensors);
我正在尝试创建一个具有传感器的时间序列,其中每个传感器提供不同的测量值(8 个值,例如:温度、嗡嗡声...),其中每个传感器的测量类型相同.每个位置的传感器数量变化:每个位置最少 2 个传感器,最多 16 个传感器。每 15 分钟进行一次测量。
问候
program Project2;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
const
cSensDiffData = 8;
cMinSensors = 2;
cMaxSensors = 16;
type
TSensorValues = record
fData : Array[0 .. cSensDiffData-1] of Integer;
end;
TSensorGroup = record
fSensorValues : TArray<TSensorValues>;
class var
fNbrSensors : Byte;
constructor Create (NbrSensors : byte);
end;
TSensorGroupSeries = record
fSensorGroup : TArray<TSensorGroup>;
class var
fSeriesLength : Integer;
constructor Create (SeriesLength : Integer; NbrSensors : Byte);
end;
{ TSensorGroup }
constructor TSensorGroup.Create (NbrSensors: Byte);
begin
case NbrSensors of
cMinSensors .. cMaxSensors :
begin
fNbrSensors := NbrSensors;
SetLength(fSensorValues, fNbrSensors);
end
else
raise Exception.Create('Nbr Sensors outside range: ' + NbrSensors.ToString + ' ' + cMinSensors.ToString + ' .. ' + cMaxSensors.ToString);
end;
end;
var
i : integer;
s : string;
SensorGroup : TSensorGroup;
SensorGroupSeries : TSensorGroupSeries;
{ TSensorGroupSeries }
constructor TSensorGroupSeries.Create(SeriesLength : Integer; NbrSensors : Byte);
var
i, j : integer;
aSensorGroup : TSensorGroup;
begin
aSensorGroup := TSensorGroup.Create(NbrSensors);
fSeriesLength := SeriesLength;
SetLength(fSensorGroup, fSeriesLength); // how is the system knowing the real length
end;
begin
// two dimensional data access is working..
SensorGroup := TSensorGroup.Create(6);
SensorGroup.fSensorValues[1].fData[2] := 12;
writeln('Nbr Sensors defined: ' + SensorGroup.fNbrSensors.ToString);
writeln('value at 0/0: ' + SensorGroup.fSensorValues[0].fData[0].ToString);
writeln('value at 1/2: ' + SensorGroup.fSensorValues[1].fData[2].ToString);
writeln('value at max: ' + SensorGroup.fSensorValues[6-1].fData[cSensDiffData-1].ToString);
readln;
// three dimensional data is causing access error
SensorGroupSeries := TSensorGroupSeries.Create(100,4);
SensorGroupSeries.fSensorGroup[5].fSensorValues[2].fData[2]:=5; // line, where error occurs
writeln(SensorGroupSeries.fSensorGroup[5].fSensorValues[2].fData[2].ToString);
readln;
end.
您正在初始化 ASensorGroup,但并未使用它。实际上,SensorGroupSeries 的 none 个元素已初始化,因此长度均为零。
这是更正后的构造函数:
constructor TSensorGroupSeries.Create(SeriesLength : Integer; NbrSensors : Byte);
var
i : integer;
begin
fSeriesLength := SeriesLength;
SetLength(fSensorGroup, fSeriesLength); // how is the system knowing the real length
for i := 0 to fSeriesLength - 1 do
begin
fSensorGroup[ i ].Create( NbrSensors );
end;
end;
我已经测试过了,它有效。
当有 1 个 Mio 传感器时,上面的三个记录可以在一个记录中声明以减少内存占用:
TSensorGroupSeries = record
// class var --> do not use class var in this context, to prevent resizing, use private or strict private
fNbrSensors : Byte;
fSeriesLength : Integer;
type
TSensorGroup = record
type
TSensorValues = record
fData : Array[0 .. cSensDiffData-1] of SmallInt;
end;
var
fSensorValues : TArray<TSensorValues>;
constructor Create (NbrSensors : byte);
end;
var
fSensorGroup : TArray<TSensorGroup>;
constructor Create (SeriesLength : Integer; NbrSensors : Byte);
end;
我在尝试使用 TArrays 在数据结构中创建第三维时遇到问题。 如何设置 TSensorGroupSeries 中的长度? --> 下面示例中的 SetLength(fSensorValues, fNbrSensors);
我正在尝试创建一个具有传感器的时间序列,其中每个传感器提供不同的测量值(8 个值,例如:温度、嗡嗡声...),其中每个传感器的测量类型相同.每个位置的传感器数量变化:每个位置最少 2 个传感器,最多 16 个传感器。每 15 分钟进行一次测量。
问候
program Project2;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
const
cSensDiffData = 8;
cMinSensors = 2;
cMaxSensors = 16;
type
TSensorValues = record
fData : Array[0 .. cSensDiffData-1] of Integer;
end;
TSensorGroup = record
fSensorValues : TArray<TSensorValues>;
class var
fNbrSensors : Byte;
constructor Create (NbrSensors : byte);
end;
TSensorGroupSeries = record
fSensorGroup : TArray<TSensorGroup>;
class var
fSeriesLength : Integer;
constructor Create (SeriesLength : Integer; NbrSensors : Byte);
end;
{ TSensorGroup }
constructor TSensorGroup.Create (NbrSensors: Byte);
begin
case NbrSensors of
cMinSensors .. cMaxSensors :
begin
fNbrSensors := NbrSensors;
SetLength(fSensorValues, fNbrSensors);
end
else
raise Exception.Create('Nbr Sensors outside range: ' + NbrSensors.ToString + ' ' + cMinSensors.ToString + ' .. ' + cMaxSensors.ToString);
end;
end;
var
i : integer;
s : string;
SensorGroup : TSensorGroup;
SensorGroupSeries : TSensorGroupSeries;
{ TSensorGroupSeries }
constructor TSensorGroupSeries.Create(SeriesLength : Integer; NbrSensors : Byte);
var
i, j : integer;
aSensorGroup : TSensorGroup;
begin
aSensorGroup := TSensorGroup.Create(NbrSensors);
fSeriesLength := SeriesLength;
SetLength(fSensorGroup, fSeriesLength); // how is the system knowing the real length
end;
begin
// two dimensional data access is working..
SensorGroup := TSensorGroup.Create(6);
SensorGroup.fSensorValues[1].fData[2] := 12;
writeln('Nbr Sensors defined: ' + SensorGroup.fNbrSensors.ToString);
writeln('value at 0/0: ' + SensorGroup.fSensorValues[0].fData[0].ToString);
writeln('value at 1/2: ' + SensorGroup.fSensorValues[1].fData[2].ToString);
writeln('value at max: ' + SensorGroup.fSensorValues[6-1].fData[cSensDiffData-1].ToString);
readln;
// three dimensional data is causing access error
SensorGroupSeries := TSensorGroupSeries.Create(100,4);
SensorGroupSeries.fSensorGroup[5].fSensorValues[2].fData[2]:=5; // line, where error occurs
writeln(SensorGroupSeries.fSensorGroup[5].fSensorValues[2].fData[2].ToString);
readln;
end.
您正在初始化 ASensorGroup,但并未使用它。实际上,SensorGroupSeries 的 none 个元素已初始化,因此长度均为零。
这是更正后的构造函数:
constructor TSensorGroupSeries.Create(SeriesLength : Integer; NbrSensors : Byte);
var
i : integer;
begin
fSeriesLength := SeriesLength;
SetLength(fSensorGroup, fSeriesLength); // how is the system knowing the real length
for i := 0 to fSeriesLength - 1 do
begin
fSensorGroup[ i ].Create( NbrSensors );
end;
end;
我已经测试过了,它有效。
当有 1 个 Mio 传感器时,上面的三个记录可以在一个记录中声明以减少内存占用:
TSensorGroupSeries = record
// class var --> do not use class var in this context, to prevent resizing, use private or strict private
fNbrSensors : Byte;
fSeriesLength : Integer;
type
TSensorGroup = record
type
TSensorValues = record
fData : Array[0 .. cSensDiffData-1] of SmallInt;
end;
var
fSensorValues : TArray<TSensorValues>;
constructor Create (NbrSensors : byte);
end;
var
fSensorGroup : TArray<TSensorGroup>;
constructor Create (SeriesLength : Integer; NbrSensors : Byte);
end;