Can't assign value to an array - c#

I have an array of tiles that are of the type Texture2D and want to set each one in the array to something different.
for (int i = 1; i <= columns * rows; i++)
{
m_tiles[i] = new Texture2D(m_graphicsDevice, tilewidth, tileheight);
}
It points to the error being the closing }
I don't understand how it being null when I'm trying to set it to not be null effects it. If I can never set the variable to anything then they'll always be null.
I have tried:
Texture2D[] m_tiles = new Texture2D(m_graphicsDevice, tilewidth, tileheight)[500];
But the compiler says "Cannot apply indexing with [] to and expression of type 'Microsoft.Xna.Framework.Graphics.Texture2D'"

You'll first need to initialize an array instance in order to assign values to its elements:
Preceed the for-loop with following statement:
Texture2D[] m_tiles = new Texture2D[columns * rows + 1];
Arrays indices are 0-based in C#, and afaik most .NET languages. So when using the indexer, you might want to loop from 0 .. n-1, instead of 1 .. n.
But honestly, I rarely ever still use arrays in .NET. If you have no specific reason to use an array, I would recommend to use a List<T> :
List<Texture2D> m_tiles = new List<Texture2D>();
for(;;)
{
m_tiles.Add(new Texture2D(foo, bar));
}

You need to instantiate the array first, like:
m_tiles = new Texture2D[10];
Like most other types, arrays need to be created, more specifically it needs to know how many elements you want it to have (in this case, it has 10 "slots").

You need to initialize the array with a proper dimension.
m_tiles[] may not be initialized to receive (columns * rows) elements.
So, before your loop, you should initialize the m_titles array with this size.
Texture2D[] m_tiles = new Texture2D[columns * rows];
So, if you have 1 columns and 1 rows, it will give you 1 slot (m_tiles[0]). If you have 2 columns and 2 rows you will have 4 slots (m_tiles[0],m_tiles[1],m_tiles[2],m_tiles[3]);
You should start you loop with i = 0 otherwise, the [0] won't be assigned and an exception of index out of bound will be trigged. If you really do not want to start with 0, you can increase by 1 the size of the array using (columns * rows +1).

Related

How can I put an array in the first index of a 2D array

I basically want to put a created array that contains student grades that I took from numericUpDowns into the first index of a 2D array so if I created another student the first one's grades won't be replaced because I would place the second's one in the second index of my 2D array and call this index.
I created and initialized an array that contains 5 indexes with 1 grade for each index and I tried to give my 2D array[i][0](with a for of course) the value of the whole grades array
static NumericUpDown[] tabGrades = new NumericUpDown[5];
NumericUpDown[][] tempGrades = new NumericUpDown[tabGrades.Length][];
...
for (int i = 0; i < tempGrades.Length; i++)
{
tempGrades[i][0] = tabGrades[];
break;
}
I expected my 2D array to simply take the array as it's first index value but instead it is telling me that I have a syntax error and that a ";" is missing
The tempGrades[i][0] represents a single element of 2D array which is of type NumericUpDown and you are trying to assign an array to that, which is an error. What you need to do is assign the array to tempGrades[i] which will represent a row(1D array) in 2D array. So you code would look like tempGrades[i][0] = tabGrades;. Your code have other issue like:
Array length should be defined while initializing them so
new NumericUpDown[tabGrades.Length][] this is an error , you have to specify the number of columns also and number of columns should be equal to the length of tabGrades.Length as only then you would be tempGrades[i] would be able to store tabGrades
why you are using a loop if you need to run the 1st iteration only. You code should like:
tempGrades[0][0] = tabGrades;
So you final code should look like:
static NumericUpDown[] tabGrades = new NumericUpDown[5];
//Here use whatever length you want instead of 10.
NumericUpDown[][] tempGrades = new NumericUpDown[10][tabGrades.Length];
...
tempGrades[0][0] = tabGrades;

Most efficient way to Array.Resize with something other than "0" as default value?

I'd like to resize an array, however I don't want all the appended values to be zero.
Array.Resize(ref range, range.Length + grow);
If you assume that the appended length is always a multiple of 4 bytes (just enough to hold a float), what is the best way to fill this up with either float.MaxValue or float.MinValue?
Just loop through the added items and assign the value to it. The compiler will produce code to only do the range checking of the array indexes once outside the loop, so the loop will be very efficient.
int oldSize = range.Length;
Array.Resize(ref range, range.Length + grow);
for (int i = oldSize; i < range.Length; i++) {
range[i] = float.MinValue;
}
You should be aware that the Array.Resize doesn't actually resize the array, but it creates a new array with the desired size and copies the data from the original array. So, if you want a way to resize a collection efficiently, you shouldn't use an array at all. Depending on your needs something like a List, a List of arrays, or a LinkedList would probably be better.

I need to create 2D array in C#

I need to create 2D jagged array. Think of a matrix. The number of rows is known, the number of columns is not known. For example I need to create array of 10 elements, where type of each element string[]. Why do I need that? The number of columns is not known - this function must simply do the allocation and pass array to some other function.
string[][] CreateMatrix(int numRows)
{
// this function must create string[][] where numRows is the first dimension.
}
UPDATE
I have C++ background. In C++ I would write the following (nevermind the syntax)
double ** CreateArray()
{
double **pArray = new *double[10]() // create 10 rows first
}
UPDATE 2
I was considering using List, but I need to have indexed-access to both rows and columns.
return new string[numRows][];
Cannot be done. However you could do something like this:
List<List<string>> createMatrix(int numRows)
{
return new List<List<string>>(numRows);
}
That allows you to be able to have a flexible amount of objects in the second dimesion.
You can write:
string[][] matrix = new string[numRows][];
and that will produce a 2D array of null elements. If you want to fill the array with non-null items, you need to write:
for (int row = 0; row < numRows; row++)
{
matrix[row] = new string[/* col count for this row */];
}
You need to specify the column count for each row of the matrix. If you don't know it in advance, you can either.
Leave the matrix items unintialised, and populate them as you know their size.
Use a fixed number that will give you room enough for the maximum possible size.
Avoid arrays and use List<> as suggested by others here.
Hope this helps.

.Net List<T> insert

I am trying to do
var test = new List< int>(10);
test.Insert(1, 0);
or
test[1] =0;
I am getting exception at this.
How can I insert to list?
Thanks
space is there to get this editor show things properly.
var test = new List<int>(10);
test.Add(1);
or
var test = new List<int>(10);
test.Insert(0, 1) // inserts the value in the first position
UPDATE
I missed your original intent. To do what you want, you just have to initialize each position in the list with an initial value. The not so suggested way would be something like:
//var test = new List<int>(10){0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
var test = new List<int>(10);
test.AddRange(Enumerable.Repeat(0, 10)); // Thanks to Ahmad
test[3] = 10; // works now
You're allocating an empty list with the capacity to hold 10 items before re-allocating. Then you're inserting into the middle of it. This is why it's failing.
edit
You seem to think that it's like an array, where it actually allocated ten slots to start with. It's not. If you want ten slots, you need to add them yourself. Once you do, it's possible to reference positions in the middle.
Assuming you want to create a list of 10 ints and set the value of 1. You could
var test = Enumerable.Repeat<int>(0, 10).ToList();
test[1] = 0;
Which would create a List of 10 ints (all equal to 0) and then set the value of index 1 to 0. Obviously as the list is initialised with values of 0, the second line is unnecessary.
Thanks for all the answers.
My list is
var x = new List<ISomeInterface>(10);
I cannot do repeat on interface and I don't know what object it is. Since it's pretty generic.
The solution I used:
var x = new ISomeInterface[10];
x.ToList();
The integer parameter of the list constructor defines the capacity of the list, which means how many elements the list can hold maximally. After you have instanciated the list, it is empty and is capable of holding 10 values (although I'm not sure if 10 isn't just the initial capacity, which will grow on demand). Anyway, when you are trying to insert at position 1 (the second element), you get an exception because the list does not contain any elements.
I think what you like to use is an array:
int[] integers = new int[10]; // Creates an array which holds 10 values,
// initially all values are zero.
integers[1] = 123; // Modifiy the value at index 1.
Best Regards
Oliver Hanappi
You cannot insert into a position until after you've added enough elements to make the list at least that large. This is clearly documented in the List's Insert documentation:
ArgumentOutOfRangeException can be thrown when:
index is less than 0, or
index is greater than Count.
If you're just trying to set specific elements, you can add in all 10 elements, then use the indexer:
test[1] = 0;
Otherwise, you can add an element, then insert:
test.Add(0); // Now the list has an element
test.Insert(1,0); // Insert into element 1...

How do you initialize a 2 dimensional array when you do not know the size

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
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.
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.
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();
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.
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.
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.

Categories

Resources