当您不知道大小时,如何初始化二维数组

我有一个二维数组,我需要加载数据。 我知道数据的宽度(22个值),但我不知道高度(估计大约4000条记录,但变量)。

我声明如下:

float[,] _calibrationSet; .... int calibrationRow = 0; While (recordsToRead) { for (int i = 0; i < SensorCount; i++) { _calibrationSet[calibrationRow, i] = calibrationArrayView.ReadFloat(); } calibrationRow++; } 

这会导致NullReferenceException,所以当我尝试像这样初始化它时:

 _calibrationSet = new float[,]; 

我得到一个“数组创建必须有数组大小或数组初始化程序。”

谢谢,基思

你不能使用数组。 或者更确切地说,您需要选择一个大小,如果您最终需要更多,那么您将不得不分配一个新的更大的数组,将旧数据中的数据复制到新数组中,然后继续执行(直到你超过新的大小……)

通常,您可以使用其中一个集合类 – ArrayList,List <>,LinkedList <>等 – 这取决于您正在寻找的内容; List将为您提供最接近我最初描述的内容,而LinkedList <>将避免频繁重新分配的问题(以较慢的访问和更大的内存使用为代价)。

例:

 List _calibrationSet = new List(); // ... while (recordsToRead) { float[] record = new float[SensorCount]; for (int i = 0; i < SensorCount; i++) { record[i] = calibrationArrayView.ReadFloat(); } _calibrationSet.Add(record); } // access later: _calibrationSet[record][sensor] 

哦,值得注意的是(正如Grauenwolf所做的那样),我在这里所做的并没有给你提供与单个多维数组相同的内存结构 - 在引擎盖下,它是对其他数组的引用数组实际上持有数据。 通过使重新分配更便宜,这可以加快构建arrays的速度,但是可以对访问速度(当然还有内存使用)产生影响。 这对您来说是否是一个问题,很大程度上取决于您在加载数据后将对数据进行的操作......以及是否有200条记录或200万条记录。

你不能在.NET中创建一个数组(而不是声明对它的引用,这是你在你的例子中所做的),而不是通过在初始化时指定一组文字值来显式地或隐式地指定它的维度。 。 (例如int [,] array4 = {{1,2},{3,4},{5,6},{7,8}};)

您需要首先使用可变大小的数据结构(22元素1-d数组的通用列表将是最简单的)然后分配您的数组并在读取完成后将数据复制到其中并且您知道有多少行你需要。

我只想使用一个列表,然后将该列表转换为数组。

你会注意到我使用了锯齿状数组(float [] [])而不是方形数组(float [,])。 除了作为“标准”的做事方式,它应该更快。 将数据从列表转换为数组时,只需复制[calibrationRow]指针即可。 使用方阵,您必须复制[calibrationRow] x [SensorCount]浮点数。

  var tempCalibrationSet = new List(); const int SensorCount = 22; int calibrationRow = 0; while (recordsToRead()) { tempCalibrationSet[calibrationRow] = new float[SensorCount]; for (int i = 0; i < SensorCount; i++) { tempCalibrationSet[calibrationRow][i] = calibrationArrayView.ReadFloat(); } calibrationRow++; } float[][] _calibrationSet = tempCalibrationSet.ToArray(); 

我通常使用更好的集合进行这种工作(List,ArrayList等),然后(如果真的有必要)在我完成时转换为T [,]。

您需要将数组预分配到最大大小(float [999,22]),或使用不同的数据结构。

我想你可以在飞行中复制/resize..(但我认为你不想)

我觉得名单听起来很合理。

您还可以使用二维ArrayList(来自System.Collections) – 您创建一个ArrayList,然后在其中放入另一个ArrayList。 这将为您提供所需的动态resize,但代价是一些开销。