I have an somewhat basic question regarding multidimensional arrays in C#.
Currently I have the following array:
float[] matrix = new float[16];
I need to create instead a 2D array with each line containing the previously mentioned 16 float numbers. Also, the number of lines in the 2D array is not known at the start of the program (i.e. it will be based on a variable).
How can I create such an array using an efficient data structure?
You could do something like this:
const Int32 arraySize = 16;
var list = new List<float[]>();
Which gives you an empty list containing zero elements (arrays) to start. As you need to add new arrays you would write this:
var array = new float[arraySize];
// do stuff to the array
And then add it to the list:
list.Add(array);
To store 16 float numbers, you could use a 4x4 matrix (which is a 4x4 2-dimensional array). For more details, check out this documentation.
// init the array
float[,] matrix = new float[4,4];
// loop through the array
for(int col = 0; col < matrix.GetLength(0); col++)
for(int row = 0; row < matrix.GetLength(1); row++)
Console.WriteLine(matrix[col, row]);
You can use multidimentional array syntax
float[,] arr2D = new float[12,12];
Alternatively, you could use a loop
float[][] floats = new float[12][];
for(int i=0; i< 12; i++)
{
floats[i] = new float[12];
}
Related
I have a 8x8x3 array with some values. What I want to do is make a list of just the 1D arrays.
What I've got so far:
int[] packIt(int[,,] data, int factor) {
List<int[]> toReturn = new List<int[]>();
int[] test = data[0, 0];
So unless I'm missing something, I make a list of one dimensional arrays and try to fit in the one dimensional array at data[0, 0] (the test is just a placeholder so far). The error I'm getting is "Wrong number of indices", however if I follow the data[0,0,0] (which gives no error) I'll just get the 1 value at the location. I could do it manually, but am just wondering if there is an implementation for the functionality that I'm trying to do, as I will be using it a lot. Thanks a bunch.
You don't need to do anything specific to turn a 3D array into a 1D one; you can just enumerate it:
foreach(var x in multiDim)
...
This will print 1 to 8:
var x = new int[2,2,2];
x[0,0,0] = 1;
x[0,0,1] = 2;
x[0,1,0] = 3;
x[0,1,1] = 4;
x[1,0,0] = 5;
x[1,0,1] = 6;
x[1,1,0] = 7;
x[1,1,1] = 8;
foreach(int i in x)
Console.WriteLine(i);
To this end you can just straight enumerate your array in chunks of whatever:
var out = new List<int[]>();
var arr = new int[chunkSize];
out.Add(arr);
var idx = 0;
foreach(var x in miltiDimArray){
if(idx == chunkSize){
out.Add(arr = new int[chunkSize]);
idx = 0;
}
arr[idx++] = i;
}
Note that I don't try to make the ticks array smaller if the chunk size doesn't divide into the number of elements. idx will have a residual value you can use to work out what to resize the last array by if that is important
So basically, I'm currently making a game and I decided to add in chunks for big maps so that it wouldn't lag. My idea was to have a main 2D array containing all tiles for my map (in integers), and a list of chunks(which are other 2D arrays).
static int[,] map;
static List<int[,]> chunks;
Say my map was 9x9 in tiles and each chunk is 3x3 in tiles. There should be in total 9 chunks within my List of chunks.
I've been thinking about this for over a week now and i haven't came up with a solution.
Even a little help will do so much.
you can achieve this using Buffer.BlockCopy and little logic.
Check the below code
static void Main(string[] args)
{
int p = 1;
int[,] array = new int[9, 9];
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
array[i, j] = p++;
}
}
GetChunkUsingBlockCopy(array, 3, 3);
}
static List<int[,]> GetChunkUsingBlockCopy(int[,] array, int row, int column)
{
int chunkcount = (array.GetLength(0) * array.GetLength(1)) / (row * column);
List<int[,]> chunkList = new List<int[,]>();
int[,] chunk = new int[row, column];
var byteLength = sizeof(int) * chunk.Length;
for (int i = 0; i < chunkcount; i++)
{
chunk = new int[row, column];
Buffer.BlockCopy(array, byteLength * i, chunk, 0, byteLength);
chunkList.Add(chunk);
}
return chunkList;
}
Hope this helps !
Please do not forget to mark this as Answer if found suitable.
First, encapsulation is your friend. Don't use multi-dimentional arrays directly in your game code, use classes. A class for a map would let you write your game code around a map without thinking of internal details of how you store your chunks. Using a class for a chunk would allow you to handle chunks easily.
Then, you might assign IDs for your chunks. Store chunks in Dictionary, where ID is the key. Map should store chunk IDs. When your map is asked about a tile at some location (x0,y0), you may calculate which chunk this tile belongs to, find an ID for your chunk, obtain the chunk from your chunks dictionary and ask it for that tile.
Sounds simple and it probably is.
I have this variable:
byte[,,] data = new byte[360,288]
And I want 4 for them.
I do not want this though:
byte[,,,] data = new byte[360,288,4]
I prefer this:
byte[,,][] data = new byte[360,288][4]
Is it possible?
Yes this is a special case of jagged arrays, one where one of the jagged dimension is multidimensional.
You should write something like this:
// Initialise 4 arrays of two dimensional arrays
byte[][,] data = new byte[4][,];
// Initialise the arrays
for (var i = data.GetLowerBound(0); i <= data.GetLowerBound(0); ++i)
data[i] = new byte[360, 258];
Of course you can invert the dimensions if you need it.
// Initialise 4 arrays of two dimensional arrays
byte[,][] data2 = new byte[360,258][];
// Initialise the arrays
for (var i = data2.GetLowerBound(0); i <= data2.GetLowerBound(0); ++i)
for (var j = data2.GetLowerBound(1); j <= data2.GetLowerBound(1); ++j)
data2[i,j] = new byte[4];
I'm doing my homework. I am assigned to create a Tic Tac Toe application, I've finished it but there's a small error, and I think I'm overlooking something, but I can't figure it out and need some new eyes to check it out because I think I'm looking at it for too long and missing a big concept.
Random r = new Random();//Creates the number generator.
int [][] numbers = new int [3][3]; //creates a 3x3 integer grid.
for (int i = 0; i< numbers.Length; i++){
for (int j=0;j<numbers[i].Length;j++){
numbers[i][j] = r.Next(2);//Traverses the array and inputs a number between 0 and 1 here.
}
}
Console.WriteLine("%d|%d|%d\n",numbers[0][0],numbers[0][1],numbers[0][2]);
Console.WriteLine("------");
Console.WriteLine("%d|%d|%d\n",numbers[1][0],numbers[1][1],numbers[1][2]);
Console.WriteLine("------");
Console.WriteLine("%d|%d|%d\n",numbers[2][0],numbers[2][1],numbers[2][2]);
The error is in the second line. Maybe I did the int [][] numbers = new int [][]; format wrong? Please help me identify what's wrong it. Thank you.
Try this when declaring your array:
int [,] numbers = new int[3,3];
You need to change your accesses to the array also fx:
numbers[i,j] = r.Next(2);
To iterate the array you can use numbers.GetLength(index) method instead of numbers.Length and numbers[i].Length.
In your case it would be something like this:
for (int i = 0; i < numbers.GetLength(0); i++)
{
for (int j = 0; j < numbers.GetLength(1); j++)
{
...
EDIT: If you really want to stay with your array of arrays (also called jagged arrays) you can initialize it like this:
int[][] numbers = new int[3][]
{
new int[3],
new int[3],
new int[3]
};
I have a function...
private double[,] AddToArray(double[,] array, double[] dataToAdd)
{
// Make a new row at the end of 'array' and copy values
// from 'dataToAdd' into the new row.
//
// Return the new, modified array.
}
However 'double[,]' isn't dynamic and I dont know what the final size of the array will be. I can create a List from it and add the new row to the list, but then I cant seem to convert it back to a double[,]. The List.ToArray() wants to output a jagged array (double[][]). This wont work. I'm interfacing with a program developed in LabVIEW and LV refuses to accept a jagged array. LV is happy with a fixed array ([,]).
Any help?
You could try this:
private double[,] AddToArray(double[,] array, double[] dataToAdd)
{
var dim0 = array.GetLength(0);
var dim1 = array.GetLength(1);
if (dim1 != dataToAdd.Length) throw new ArgumentException();
var na = new double[dim0 + 1, dim1];
Array.Copy(array, na, array.Length);
for (var i = 0; i < dim1; ++i) na[dim0, i] = dataToAdd[i];
return na;
}
It explicitly increments the high-order dimension by one, and also verifies that the length of the low-order dimension is equal to the dataToAdd array. I have not been able to any smarter copying from dataToAdd to the 2D array than by a for loop; it is not possible to apply Array.Copy for different ranked arrays.
You could always create the 2-dimensional array manually:
double[,] array = new double[list.Count, data.Length];
for(int i = 0;i < list.Count;++i)
for(int j = 0;j < data.Length;++j)
array[i, j] = list[i][j];
That is, of course, assuming that all of the 'dataToAdd' is of uniform length. Otherwise, what do you fill in the array for unused elements?