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

发布于 2024-07-05 12:32:21 字数 519 浏览 10 评论 0原文

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

我得到“数组创建必须具有数组大小或数组初始值设定项”。

谢谢你, 基思

I have a two dimensional array that I need to load data into. I know the width of the data (22 values) but I do not know the height (estimated around 4000 records, but variable).

I have it declared as follows:

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

This causes a NullReferenceException, so when I try to initialize it like this:

_calibrationSet = new float[,];

I get an "Array creation must have array size or array initializer."

Thank you,
Keith

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

勿挽旧人 2024-07-12 12:32:25

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

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

我认为这个列表听起来很合理。

you would either need to preallocate the array to a Maximum size (float[999,22] ) , or use a different data structure.

i guess you could copy/resize on the fly.. (but i don't think you'd want to)

i think the List sounds reasonable.

來不及說愛妳 2024-07-12 12:32:25

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

You could also use a two-dimensional ArrayList (from System.Collections) -- you create an ArrayList, then put another ArrayList inside it. This will give you the dynamic resizing you need, but at the expense of a bit of overhead.

美人如玉 2024-07-12 12:32:24

我通常使用更好的集合来完成此类工作(List、ArrayList 等),然后(如果确实有必要)在完成后转换为 T[,]。

I generally use the nicer collections for this sort of work (List, ArrayList etc.) and then (if really necessary) cast to T[,] when I'm done.

_蜘蛛 2024-07-12 12:32:24

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

您会注意到这里我使用了锯齿状数组(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();

I would just use a list, then convert that list into an array.

You will notice here that I used a jagged array (float[][]) instead of a square array (float [,]). Besides being the "standard" way of doing things, it should be much faster. When converting the data from a list to an array you only have to copy [calibrationRow] pointers. Using a square array, you would have to copy [calibrationRow] x [SensorCount] floats.

        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();
十二 2024-07-12 12:32:23

如果不显式或隐式地在初始化数组时指定一组文字值,则无法在 .NET 中创建数组(而不是声明对它的引用,这就是您在示例中所做的) 。 (例如 int[,] array4 = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };)

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

You can't create an array in .NET (as opposed to declaring a reference to it, which is what you did in your example) without specifying its dimensions, either explicitly, or implicitly by specifying a set of literal values when you initialize it. (e.g. int[,] array4 = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };)

You need to use a variable-size data structure first (a generic list of 22-element 1-d arrays would be the simplest) and then allocate your array and copy your data into it after your read is finished and you know how many rows you need.

梅窗月明清似水 2024-07-12 12:32:22

你不能使用数组。
或者更确切地说,您需要选择一个大小,如果您最终需要更多,那么您将必须分配一个新的、更大的数组,将数据从旧的数组复制到新的数组中,然后像以前一样继续(直到你超出了新集合的大小...)

通常,你会选择集合类之一 - ArrayList、List<>、LinkedList<> 等 - 哪一个在很大程度上取决于你正在寻找的内容为了; List 将为您提供与我最初描述的最接近的内容,而 LinkedList<> 将为您提供最接近的内容。 将避免频繁重新分配的问题(以更慢的访问速度和更大的内存使用为代价)。

示例:

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 万条记录。

You can't use an array.
Or rather, you would need to pick a size, and if you ended up needing more then you would have to allocate a new, larger, array, copy the data from the old one into the new one, and continue on as before (until you exceed the size of the new one...)

Generally, you would go with one of the collection classes - ArrayList, List<>, LinkedList<>, etc. - which one depends a lot on what you're looking for; List will give you the closest thing to what i described initially, while LinkedList<> will avoid the problem of frequent re-allocations (at the cost of slower access and greater memory usage).

Example:

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]

Oh, and it's worth noting (as Grauenwolf did), that what i'm doing here doesn't give you the same memory structure as a single, multi-dimensional array would - under the hood, it's an array of references to other arrays that actually hold the data. This speeds up building the array a good deal by making reallocation cheaper, but can have an impact on access speed (and, of course, memory usage). Whether this is an issue for you depends a lot on what you'll be doing with the data after it's loaded... and whether there are two hundred records or two million records.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文