C# 不知道大小时如何初始化二维数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/50558/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you initialize a 2 dimensional array when you do not know the size
提问by Keith Sirmons
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).
我有一个二维数组,我需要将数据加载到其中。我知道数据的宽度(22 个值)但我不知道高度(估计大约 4000 条记录,但可变)。
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:
这会导致 NullReferenceException,所以当我尝试像这样初始化它时:
_calibrationSet = new float[,];
I get an "Array creation must have array size or array initializer."
我收到“数组创建必须具有数组大小或数组初始值设定项”。
Thank you, Keith
谢谢你,基思
采纳答案by Shog9
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).
通常,您会使用集合类之一 - ArrayList、List<>、LinkedList<> 等 - 哪个在很大程度上取决于您要查找的内容;List 会给你最接近我最初描述的东西,而 LinkedList<> 将避免频繁重新分配的问题(以较慢的访问和更大的内存使用为代价)。
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 Grauenwolfdid), 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.
哦,值得注意(正如Grauenwolf所做的那样),我在这里所做的不会为您提供与单个多维数组相同的内存结构 - 在引擎盖下,它是对其他数组的引用的数组实际保存数据。这通过使重新分配更便宜来大大加快构建阵列的速度,但可能会影响访问速度(当然还有内存使用)。这对您来说是否是一个问题在很大程度上取决于您在加载数据后将如何处理……以及是否有 200 条记录或 200 万条记录。
回答by McKenzieG1
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 } };)
你不能在 .NET 中创建一个数组(而不是声明一个对它的引用,这就是你在你的例子中所做的)而不通过在初始化时明确或隐式地指定一组文字值来指定它的维度. (例如 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.
您需要首先使用可变大小的数据结构(22 元素一维数组的通用列表将是最简单的),然后在读取完成后分配数组并将数据复制到其中,并且您知道有多少行你需要。
回答by Daren Thomas
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.
我通常将更好的集合用于此类工作(List、ArrayList 等),然后(如果确实需要)在我完成后转换为 T[,]。
回答by ShoeLace
you would either need to preallocate the array to a Maximum size (float[999,22] ) , or use a different data structure.
您需要将数组预先分配为最大大小 (float[999,22]),或者使用不同的数据结构。
i guess you could copy/resize on the fly.. (but i don't think you'd want to)
我想你可以即时复制/调整大小..(但我认为你不会想要)
i think the List sounds reasonable.
我认为清单听起来很合理。
回答by Jonathan Allen
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.
您会注意到这里我使用了锯齿状数组 (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();
回答by Guy Starbuck
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.
您还可以使用二维 ArrayList(来自 System.Collections)——您创建一个 ArrayList,然后将另一个 ArrayList 放入其中。这将为您提供所需的动态调整大小,但会增加一些开销。