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

时间:2008-09-08 20:09:46

标签: c# array-initialize

我有一个二维数组,我需要将数据加载到。我知道数据的宽度(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[,];

我得到“数组创建必须有数组大小或数组初始化器。”

谢谢你, 基思

6 个答案:

答案 0 :(得分:8)

您无法使用数组。 或者更确切地说,你需要选择一个大小,如果你最终需要更多,那么你将不得不分配一个新的,更大的数组,将数据从旧的数据复制到新的数组中,并继续像以前一样(直到你超过新的大小...)

一般来说,你会选择其中一个集合类--ArrayList,List&lt;&gt ;, LinkedList&lt;&gt;等等 - 哪一个很大程度上依赖于你正在寻找的东西; List会给你最接近我最初描述的东西,而LinkedList&lt;&gt;将避免频繁重新分配的问题(以较慢的访问和更大的内存使用为代价)。

示例:

List<float[]> _calibrationSet = new List<float[]>();

// ...

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所做的那样),我在这里所做的并没有给你带来与单个多维数组相同的内存结构 - 在引擎盖下,它是实际保存数据的其他数组的引用数组。通过使重新分配更便宜,这可以加快构建阵列的速度,但是可以对访问速度(当然还有内存使用)产生影响。这对你来说是否是一个问题很大程度上取决于你在加载后对数据的处理方式......以及是否有200条记录或200万条记录。

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

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

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

        var tempCalibrationSet = new List<float[]>();
        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();

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

我想你可以动态复制/调整大小..(但我认为你不想这样做)

我认为名单听起来很合理。

答案 5 :(得分:0)

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