This question already has answers here:
Differences between a multidimensional array "[,]" and an array of arrays "[][]" in C#?
(12 answers)
Closed 9 years ago.
What is the difference between the two syntaxes?
The first one is a multi dimensional array while the second is a jagged array. You can take a look at this question to get a description of the diffrerence between the two, but here is an important snippit:
A multidimensional array creates a nice linear memory layout while a
jagged array implies several extra levels of indirection.
Looking up the value jagged[3][6] in a jagged array var jagged = new
int[10][5] works like this: Look up the element at index 3 (which is
an array) and look up the element at index 6 in that array (which is a
value). For each dimension in this case, there's an additional look up
(this is an expensive memory access pattern).
A multidimensional array is laid out linearly in memory, the actual
value is found by multiplying together the indexes. However, given the
array var mult = new int[10,30] the Length property of that
multidimensional array returns the total number of elements i.e. 10 *
30 = 300.
The Rank property of a jagged array is always 1, but a
multidimensional array can have any rank. The GetLength method of any
array can be used to get the length of each dimension. For the
multidimensional array in this example mult.GetLength(1) returns 30.
Indexing the multidimensional array is faster e.g. given the
multidimensional array in this example mult[1,7] = 30 * 1 + 7 = 37,
get the element at that index 37. This is a better memory access
pattern because only one memory location is involved, which is the
base address of the array.
A multidimensional array therefore allocates a continuous memory
block, while a jagged array does not have to be square like. e.g.
jagged1.Length does not have to equal jagged[2].Length which would
be true for any multidimensional array.
Update:
One major difference between the multi and jagged array is that a multi must always be "square", meaning that any two indexes will have the same number of elements in their child arrays. A jagged array does not have this requirement. Take a look at the code below:
var jagged = new int[3][]; //not defining the size of the child array...
var multi = new int[3,8]; //defining a 3x8 "square"
var multiBad = new int[3,]; //Syntax error!
var jaggedSquare= new int[3][8]; //another 3x8 "square"
The former is a two dimensional array. The latter is an array whose elements are also arrays.
The first is for a multidimentional array
the second is for array of arrays
Related
I have a 2 dimensional array with rows that change in length. But with .GetLength(1) i only get the length of the first row in the second dimension.
How can i get the size of any specific row in an array?
What you are describing sounds more like a jagged array (array of arrays). That would look like this:
int rowLength = My2dArray[rowIndex].Length;
If you really have a 2D array, then all the rows are required to be the same size, which is set when you first allocate the array. On the other hand, if you do have a jagged array then .GetLength(1) will throw an exception; it does not return the length of the first row as claimed.
Of course, this confusion could be avoided if you showed us how the collection is created and populated.
I have a function that can take a 1d array (double[]) as an argument while my source data is a 2d array (double[,]) of 'cnt' number of 3d points, like so
double[,] points = new double[3,cnt]
But what I actually want to do is to pass on each of the three 2nd dim arrays to the function gpu.Average(double[] arg), preferably without having to copy the content of the arrays value[i] by value[i]. Is that possible in C#?
EXAMPLE CODE
This works:
double[] points1d = new double[cnt];
// ... fill points1d with data, then
double a = gpu.Average(points1d); // <- Alea.gpu.Average() accepts a 1d array
But as said, I want to pass on the second dimension to the function gpu.Average() whithout having to run for-loops three times to copy into 1d arrays:
double[,] points2d = new double[3,cnt];
// ... fill points2d with 'cnt' items of data and
// then pass it on
double x = gpu.Average(points2d[0,??]); // How to pass on 2nd dim?
double y = gpu.Average(points2d[1,??]);
double z = gpu.Average(points2d[2,??]);
Is this possible without having to copy the data into 1d arrays?
(BTW, calculating average is not a good example use of gpu parallel library, this is just a test case comparing execution times for different data types & structures).
// Rolf
No this is not possible in managed code without copying the contents of e.g. points2d[1,*] to a new single dimensional array.
In managed code every array has to know its length, so that every index access can be checked and ArrayIndexOutOfBounds exception thrown if the index is out of bounds. The length (integer value) is stored before the first element of the array, so that the runtime knows where to find it. Now with this I guess one can see why you cannot split array into several parts and treat those as new arrays. Note that the story is even more complicated for multidimensional arrays, which have to store the number of dimensions and the size of each dimension...
What you can do is to use jagged array:
double[][] points2d = new double[3][];
points2[0] = new double[cnt];
...
gpu.Average(points2d[0]);
Jagged arrays are faster than multidimensional arrays and are recommended to be used instead of multidimensional arrays even by MS.
I just saw this question and infact tried to answer it as well. But while answering I thought what could be the answer in case of C#? I am looking for some MSDN doc or any relevant source like in Java
What is the maximum dimension allowed for an array in C# like a[1][1][1][1]....[1]. I tried to search on SO but was not able to find.
The best I got up to was that "An array could theoretically have at most 2,147,483,647 elements, since it uses an int for indexing."
Also I am aware of the fact that Maximum Size that an Array can hold is
System.Int32.MaxValue
Kindly do let me know if this is a duplicate I will delete my question.
The limit is 32. I checked it with the code:
var b = Array.CreateInstance(typeof (int), new int[32]);
var a = Array.CreateInstance(typeof (int), new int[33]);
It applies for both 64 and 32-bit targeted applications.
Actually, I needn't have googled it. Straight from MSDN:
An element is a value in an Array. The length of an Array is the total number of elements it can contain. The rank of an Array is the number of dimensions in the Array. The lower bound of a dimension of an Array is the starting index of that dimension of the Array; a multidimensional Array can have different bounds for each dimension. An array can have a maximum of 32 dimensions.
About jagged arrays
However, I just noticed that the syntax you used in your edit (and also the syntax Peter used in the comments below) isn't how multi-dimensional arrays are defined in C#. Multi-dimensional arrays are defined as:
int[,,,] arr = new int[0,0,0];
And they are arrays of regular integers, that happen to have multiple dimensions. The syntax:
int[][][] = new int[0][][];
Defines something that in C# is called a jagged array. Jagged arrays are just regular, single-dimensional arrays that happen to have other arrays as elements. You can have multi-dimensional arrays of jagged arrays, or the other way around, as the MSDN article points out.
They are treated differently, however. Jagged arrays are just arrays of (effectiely) regular* objects, and as such, aren't regulated in the same way as multi-dimensional arrays. There is no theoretical limit to the number of "dimensions" a jagged array can have, and in fact the CLR happily let me run the following code:
Array arr = new int[0];
for (int i = 0; i < Int32.MaxValue - 1; i++) {
var newArr = Array.CreateInstance(arr.GetType(), 1);
newArr.SetValue(arr, 0);
arr = newArr;
}
Right up until my system became completely unresponsive and crashed. No exception was thrown.
Limiting the loop to 1000 iterations, you find that the type of the resulting array is:
System.Int32[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]...
In addition, although I can't find a source for this, the number of dimensions a jagged array can have probably isn't even limited by the single object memory limitation, because each array only has references to objects. For example, a jagged array of (eventually) Int32 with a nesting factor of, say, 1000 and 2 elements per array, would take up a negligible amount of memory (that is, on its own), but all the arrays combined would take up an exponential amount.
* With a little bit of syntax sugar. A more syntactically correct way of encoding jagged arrays would be: int[][] arr = new int[][0]; because int[] is the element type.
It's implementation defined
The number of dimensions an array can have appears to be implementation-defined. The number doesn't appear anywhere in the CLI specification, and the code provided by Peter below runs fine on Ideone's mono-2.8, where it appears the limit is 255.
You may feel weird about what I'm asking, but it's true, convert 1 two-dimensional array into 2 one-dimensional arrays.
That was what my teacher asked, and he said he would give a perfect point for whoever answers this (I think, tricky) question. I would happy to convert any 2 or n-dimensional array into one one-dimensional array. But he said 2, so I think there must be something to do with the second array. And, he didn't tell what type of array (int, String or object), so I assume it must be done with any kind of 2-dimensional array.
This is what I will answer him if no one here figure out what he wants: Convert into a 1-dimensional array, and leave the second null (or let it have no element). But I don't think it's a good answer for such a tricky question.
EDIT: Here is my teacher question, word-by-word (he just ask at the end of the session in voice, not in the textbook, as a bonus question(with... a nice bonus reward)): Given a 2-dimensional array, convert it into two 1-dimensional arrays.
I don't know if [][] in Java and C# considered 2-dimensional array, but C# does have [, ], which is 2-dimensional array. We are studying computer algorithm, with no target IDE or language.
EDIT2: I emailed him, and he refused to give additional information (he said it was unfair for others if I have more information than them), and he didn't give any comments about jagged array idea. The only useful thing in his reply: Let [][] be considered 2-dimensional array.
I'll bite. It's possible to flatten the entire two-dimensional array into the first of the two one-dimensional arrays by simply reading and writing consistently. I.e. store row 1 then row 2, etc. sequentially in that first array. Whenever you move to the next row, store the index of that next cell (of the first one dimensional array) in the second one-dimensional array, which would essentially become a row index table.
As Jon Skeet said above, this isn't a very well-specified question; perhaps with clarified information, we could better help you.
If I understand your question properly
it's easy m8...
it's only an algorithm question.. not a programming language specific...
you can do it like this:
one array holds the values
second array holds the keys
try to find a workaround in the second array to know what keys you've got..
For example:
array_1: v0 v1 v2 null v3 v4 v5 null v6 v7 v8 null
array_2: 0 1 2 newR 0 1 2 newR 0 1 2 newR
You can represent it in one array as well... but you need a specific algorithm to figure out when you are located on Y of the matrix.
The problem is that you won't access the data instantly from memory.. this is why there are bi-dimensional arrays
Another way:
keep in array 1 the values
keep in the second array the keys as string like in the following example:
array1: value1 value2 value3 value4 value5
array2: 0,0 0,1 1,0 1,1 2,0
there are a lot of algorithms but I don't think you will find better than bi-dimensional arrays...
When you look after them you will have less performance.. ofc.. unless you keep them in hashtables.. hashing 0,0 and added as key in a hashtable and add the specified value to that key. then you will look for key "0,0"...
Flatten the 2-d array in either row-major or column-major order, storing it in one of the 1-d arrays. Store the shape {n, m} of the array in the other 1-d integer array. Given the indices for an element in the 2-d array of values, you can use the shape to calculate the index in the 1-d array of values.
The two representations are isomorphic, and both allow looking up the values in constant time. It's also similar to how a 2-d array is represented in memory.
I guess you want to transform you 2-demension array (typed RelevantType[,]) into 2 arrays (typed SomeTypeA[] and SomeTypeB[]) without losing any information?
It's not very difficult:
Have the first array be of type RelevantType[], the second one of type int[], copy the content of your 2-dimensionnal array into the first one and its first indices into the second one, and you're done.
I have a code that looks like (more or less) :
public void INeedHolidaysNow(double[,]){
//... Code to take a break from coding and fly to Hawaii
}
double[][] WageLossPerVacationDay = new double[10][5];
INeedHolidays(WageLossPerVacationDay); // >>throws the Exception in the Title
I found the solution on this post which consists in looping rather thant trying a savage cast
So my question is : WHY ? what happens behind the scenes in the memory allocation that prevents what may seem - at least at first glance, to be a feasible cast ? I mean structurally, both expression seem to be quite identic. What is it that I am missing here ?
EDIT:
I have to use "double[ ][ ]" as it is provided by an external library.
One is a jagged array, the other is one big block.
double[][] is an array that contains arrays of double. Its form is not necessarily rectangular. In c terms its similar to a double**
double[,] is just one big block of memory, and it is always rectangular. In c terms it's just a double* where you use myArray[x+y*width] to access an element.
One is called multidimensional array (double[*,*]) and other is called jagged array (double[][]).
Here is a good discussion over differences between them.
What is differences between Multidimensional array and Array of Arrays in C#?
Quite simply, [,] arrays (2D arrays) and [][] arrays (jagged arrays) aren't the same.
A [,] array can be visually represented by a rectangle (hence it's also known as a rectangular array), while a [][] array is a 1D array that contains other 1D arrays.
It wouldn't make much sense to be able to cast one to the other.
You should define your double array like this:
double[,] WageLossPerVacationDay = new double[3, 5];
Then it should work!
hth