In my project I have a lot of code like this:
int[][] a = new int[firstDimension][];
for (int i=0; i<firstDimension; i++)
{
a[i] = new int[secondDimension];
}
Types of elements are different.
Is there any way of writing a method like
createArray(typeof(int), firstDimension, secondDimension);
and getting new int[firstDimension][secondDimension]?
Once again, type of elements is known only at runtime.
Generics should do the trick:
static T[][] CreateArray<T>(int rows, int cols)
{
T[][] array = new T[rows][];
for (int i = 0; i < array.GetLength(0); i++)
array[i] = new T[cols];
return array;
}
You do have to specify the type when calling this:
char[][] data = CreateArray<char>(10, 20);
Well you can do this:
int[,] array = new int[4,2];
What you get is called a multidimensional array (4x2). Here is a nice article about multidimensional arrays.
The term jagged array usually refers to arrays, that have different second dimensions. For example take:
int[][] jagged = new int[2][];
jagged[0] = new int[5]; // 5 elements
jagged[1] = new int[1]; // 1 element
so this is not a 2x5 array, but a jagged array..
If:
You definitely want a jagged array, and not a multi-dimensional one as mOsa mentions.
You definitely need it to be of dynamic type at runtime, and not at compile time using generics as Henk mentions.
You can use Array.CreateInstance something like:
static Array CreateArray (Type t, int rows, int cols)
{
Array arr = Array.CreateInstance (typeof(Array), rows);
for (int i = 0; i < rows; rows++) {
arr.SetValue (Array.CreateInstance(t, cols), i);
}
return arr;
}
But are you sure you need this to by dynamic type at runtime?
As mOsa mentioned, if you want rectangular jagged array, then you are better off using a multi-dimensional array.
int[,] array = new int[dimension, dimension2];
will generate a rectangular array.
The reason to use a jagged array, is if you want to create an array with different secondary dimensions. A jagged array is really an array of arrays, where as a multi-dimensional array is a slightly different beast.
Related
I frequently make use of jagged arrays in my programming. Often, they'll be static in size, but I'll be re-filling them with new data. In the past, I've just made use of the 'new' operator to wipe out the array, and then just re-initialise it. However, I suspect that it's probably not best practice.
Any advice on the best method to clear a jagged array out and zero all its values?
I'm familiar with Array.Clear, but as far as I'm aware, because Jagged arrays aren't technically contiguous, I believe I have to loop and clear each child individually?
Thanks in advance!
Jaspar
I would use Array.Clear()
int[][] jagged = new int[][] {
new int[] { 1, 2, 3, 4 },
new int[] { 11, 12 },
new int[] { 21, 22, 23 }
};
for (int i = 0; i < jagged.Length; i++)
{
Array.Clear(jagged[i], 0, jagged[i].Length);
}
instead of
for (int i = 0; i < jagged.Length; i++)
{
for (int j = 0; j < jagged[i].Length; j++)
{
jagged[i][j] = 0;
}
}
Yes, I believe that you will have to loop on the sub array.
A jagged array is an array of array. The default( refenence type ) is a null reference. So a Clear jagged array will be here an array of null references.
But you want each member of those array to be cleared so :
foreach (int[] subArray in jaggedArr)
{
Array.Clear (subArray, 0, subArray.Length);
}
It is enough to remove all existing references by assigning null to make array ready for Garbage Collection. (array=null)
Then it is possible to force garbage collection by calling (array.Collect()),
I am trying to solve a challenge on a coding site. The problem is about int matrixes. I am using c# language.I need to create a function that takes a parameter as int[][] (integer matrix) and also return int[][] (another integer matrix). Starting of problem (the empty function given to me) is like that
int[][] boxBlur(int[][] image) {
}
and this is what i tried so far
int[][] boxBlur(int[][] image) {
int pixelLength = image[0].Length - 2;
int[][] newBox = new int[pixelLength][pixelLength];
int pixelSum = 0;
int c = 0;
for(int t = 0; t<pixelLength; t++)
{
for(int i = 0; i<pixelLength; i++)
{
for(int j = t; j < 3 + t ; j++)
{
for(int k = i; k < i+3 ; k++)
{
pixelSum += image[j][k];
}
}
newBox[t][i] = pixelSum / 9;
}
}
return newBox;
}
Now i don't have any problem with algorithm, probably it will work but the problem is that i can't define an Array like int[][]. It gives an error like Cannot implicitly convert type int to int[][] and when i try to create this array like
int[,] newBox = new int[pixelLength,pixelLength];
it also gives error because it says the return type is wrong and i can't change the return type so i need to define a matrix exactly like int[][].
Is there any way to do it or do i need to try another way?
int[][] is a jagged array, or in other words, an array of arrays.
When you see a int[], you understand it as an array of integers. That is, every "slot" of the array holds and integer. An array of arrays is exactly the same, except that every slot holds an array.
Once you understand that, it should make perfect sense why the correct way to initialize your jagged array is:
int[][] newBox = new int[pixelLength][];
Now you've said that newBox is an array of int arrays: newBox[0] is of type int[], newBox[1] is of type int[], etc. Because the default value of an array, like any other reference type, is null, the value of newBox[0], newBox[1], etc. is null; you need to initialize each and every one of them.
The advantage of jagged arrays is, of course, that each int[] can be the size you wish, hence the name jagged array.
So what you are essentially missing, once you initialize your jagged array correctly, is initalizing each and everyone of the int[] arrays before using them. You can do this inside the adequate loop.
Carrying on from here should be easy.
An interesting test to verify if you've understood everything correctly is initalizing and correctly filling up all the values of the following type:
int[][][] myHeadHurtsArray;
int[][] and int[,] are two different things. The first is Jagged Array, the second is Multidimensional Array.
When initializing jagged array you can give only the array length, not the length of all the arrays in it:
int[][] newBox = new int[pixelLength][];
And insert new array each time:
newBox[index] = new int[size];
This question already has answers here:
Differences between a multidimensional array "[,]" and an array of arrays "[][]" in C#?
(12 answers)
Closed 9 years ago.
double[][] ServicePoint = new double[10][9]; // <-- gives an error (1)
double[,] ServicePoint = new double[10,9]; // <-- ok (2)
What's their difference? (1) yields an error, what's the reason?
And
double d = new double[9]
ServicePoint[0] = d;
using (2) will prompt an error. Why?
One is an array of arrays, and one is a 2d array. The former can be jagged, the latter is uniform.
That is, a double[][] can validly be:
double[][] x = new double[5][];
x[0] = new double[10];
x[1] = new double[5];
x[2] = new double[3];
x[3] = new double[100];
x[4] = new double[1];
Because each entry in the array is a reference to an array of double. With a jagged array, you can do an assignment to an array like you want in your second example:
x[0] = new double[13];
On the second item, because it is a uniform 2d array, you can't assign a 1d array to a row or column, because you must index both the row and column, which gets you down to a single double:
double[,] ServicePoint = new double[10,9];
ServicePoint[0]... // <-- meaningless, a 2d array can't use just one index.
UPDATE:
To clarify based on your question, the reason your #1 had a syntax error is because you had this:
double[][] ServicePoint = new double[10][9];
And you can't specify the second index at the time of construction. The key is that ServicePoint is not a 2d array, but an 1d array (of arrays) and thus since you are creating a 1d array (of arrays), you specify only one index:
double[][] ServicePoint = new double[10][];
Then, when you create each item in the array, each of those are also arrays, so then you can specify their dimensions (which can be different, hence the term jagged array):
ServicePoint[0] = new double[13];
ServicePoint[1] = new double[20];
In the first instance you are trying to create what is called a jagged array.
double[][] ServicePoint = new double[10][9].
The above statement would have worked if it was defined like below.
double[][] ServicePoint = new double[10][]
what this means is you are creating an array of size 10 ,that can store 10 differently sized arrays inside it.In simple terms an Array of arrays.see the below image,which signifies a jagged array.
http://msdn.microsoft.com/en-us/library/2s05feca(v=vs.80).aspx
The second one is basically a two dimensional array and the syntax is correct and acceptable.
double[,] ServicePoint = new double[10,9];//<-ok (2)
And to access or modify a two dimensional array you have to pass both the dimensions,but in your case you are passing just a single dimension,thats why the error
Correct usage would be
ServicePoint[0][2] ,Refers to an item on the first row ,third column.
Pictorial rep of your two dimensional array
double[][] are called jagged arrays , The inner dimensions aren’t specified in the declaration. Unlike a rectangular array, each inner array can be an arbitrary length. Each inner array is implicitly initialized to null rather than an empty array. Each inner array must be created manually: Reference [C# 4.0 in nutshell The definitive Reference]
for (int i = 0; i < matrix.Length; i++)
{
matrix[i] = new int [3]; // Create inner array
for (int j = 0; j < matrix[i].Length; j++)
matrix[i][j] = i * 3 + j;
}
double[,] are called rectangular arrays, which are declared using commas to separate each dimension. The following piece of code declares a rectangular 3-by-3 two-dimensional array, initializing it with numbers from 0 to 8:
int [,] matrix = new int [3, 3];
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
matrix [i, j] = i * 3 + j;
double[,] is a 2d array (matrix) while double[][] is an array of arrays (jagged arrays) and the syntax is:
double[][] ServicePoint = new double[10][];
double[][] is an array of arrays and double[,] is a matrix. If you want to initialize an array of array, you will need to do this:
double[][] ServicePoint = new double[10][]
for(var i=0;i<ServicePoint.Length;i++)
ServicePoint[i] = new double[9];
Take in account that using arrays of arrays will let you have arrays of different lengths:
ServicePoint[0] = new double[10];
ServicePoint[1] = new double[3];
ServicePoint[2] = new double[5];
//and so on...
I am creating an array of arrays such that:
var arrNewArray = new string[arrOldArray.Length][7];
arrOldArray is an array of arrays such that it's [X][4], meaning the length of the 1st array or "outside" array can change, but the length of the "inside" array is ALWAYS 4, or hold 4 strings ([0][1][2][3]).
Why won't the compiler accept my statement above?
Essentially, I'm trying to take arrOldArray and expand it, or add a few more "columns" by increasing the [4] in the old array to a [7] in the new array and then copy the contents over. Perhaps I'm not doing it the best/efficient way, so any guidance would be appreciated thanks.
I think you want a two dimensional array:
var arrNewArray = new string[arrOldArray.Length, 7];
You would access it like this: arrNewArray[x, y].
This is better than a jagged array, because it clearly communicates that the number of "columns" is the same for every row.
If you want to continue using a jagged array, you need to do it like this:
var arrNewArray = new string[arrOldArray.Length][];
for(int i = 0; i < arrOldArray.Length; ++i)
arrNewArray[i] = new string[7];
The reason for this convoluted way is: With a jagged array, each "row" can have a different number of "columns". A short-hand syntax for the case where each "row" has the same number of "columns" doesn't exist. That's why your code doesn't compile.
A jagged array is essential an array of arrays, so you need to create a new array instance for each "row" of the outer array and explicitly assign it. That's what the for loop is doing.
You can't use Array.Copy with jagged arrays. Each child-array is it's own instance and Array.Copy doesn't make a deep copy, it merely copies the references from one array to another. The effect would be, that both arrays would point to the same items and changing an item in one array would be seen from the other.
You are not creating the jagged array properly. The proper way is to create the first dimension of the jagged array and then loop through the items of the first dimension to create the nested arrays and copy the data from the old arrays. Here's an example:
int newSize = 7;
string[][] newArray = new string[oldArray.Length][];
for (int i = 0; i < oldArray.Length; i++)
{
newArray[i] = new string[newSize];
Array.Copy(oldArray[i], newArray[i], oldArray[i].Length);
}
You would be wanting
var arrNewArray = new string[arrOldArray.Length, 7];
var arrNewArray = new[] {new string[7]};//array of arrays
var arrNewArray = new string[arrOldArray.Length, 7];//two-dimensional array
Using Linq:
int[][] jaggedArray2 = new int[][]
{
new int[] {1,3,5,7,9},
new int[] {0,2,4,6},
new int[] {11,22}
};
int length = jaggedArray.Sum(a => a.Length);
I don't believe what you're asking is directly possible. Because the syntax that you are using is for a jagged array, and what you are doing is effectively asking it to create a multi-dimensional array.
The syntax is confusing since it reads like what you really want is a multi-dimensional array (although I'm aware that's not the case.)
I don't believe you could store your arrays in the newly allocated array either due to a size change. You would need to build a custom copy method to move the data into the larger array.
This question already has answers here:
Differences between a multidimensional array "[,]" and an array of arrays "[][]" in C#?
(12 answers)
Closed 9 years ago.
double[][] ServicePoint = new double[10][9]; // <-- gives an error (1)
double[,] ServicePoint = new double[10,9]; // <-- ok (2)
What's their difference? (1) yields an error, what's the reason?
And
double d = new double[9]
ServicePoint[0] = d;
using (2) will prompt an error. Why?
One is an array of arrays, and one is a 2d array. The former can be jagged, the latter is uniform.
That is, a double[][] can validly be:
double[][] x = new double[5][];
x[0] = new double[10];
x[1] = new double[5];
x[2] = new double[3];
x[3] = new double[100];
x[4] = new double[1];
Because each entry in the array is a reference to an array of double. With a jagged array, you can do an assignment to an array like you want in your second example:
x[0] = new double[13];
On the second item, because it is a uniform 2d array, you can't assign a 1d array to a row or column, because you must index both the row and column, which gets you down to a single double:
double[,] ServicePoint = new double[10,9];
ServicePoint[0]... // <-- meaningless, a 2d array can't use just one index.
UPDATE:
To clarify based on your question, the reason your #1 had a syntax error is because you had this:
double[][] ServicePoint = new double[10][9];
And you can't specify the second index at the time of construction. The key is that ServicePoint is not a 2d array, but an 1d array (of arrays) and thus since you are creating a 1d array (of arrays), you specify only one index:
double[][] ServicePoint = new double[10][];
Then, when you create each item in the array, each of those are also arrays, so then you can specify their dimensions (which can be different, hence the term jagged array):
ServicePoint[0] = new double[13];
ServicePoint[1] = new double[20];
In the first instance you are trying to create what is called a jagged array.
double[][] ServicePoint = new double[10][9].
The above statement would have worked if it was defined like below.
double[][] ServicePoint = new double[10][]
what this means is you are creating an array of size 10 ,that can store 10 differently sized arrays inside it.In simple terms an Array of arrays.see the below image,which signifies a jagged array.
http://msdn.microsoft.com/en-us/library/2s05feca(v=vs.80).aspx
The second one is basically a two dimensional array and the syntax is correct and acceptable.
double[,] ServicePoint = new double[10,9];//<-ok (2)
And to access or modify a two dimensional array you have to pass both the dimensions,but in your case you are passing just a single dimension,thats why the error
Correct usage would be
ServicePoint[0][2] ,Refers to an item on the first row ,third column.
Pictorial rep of your two dimensional array
double[][] are called jagged arrays , The inner dimensions aren’t specified in the declaration. Unlike a rectangular array, each inner array can be an arbitrary length. Each inner array is implicitly initialized to null rather than an empty array. Each inner array must be created manually: Reference [C# 4.0 in nutshell The definitive Reference]
for (int i = 0; i < matrix.Length; i++)
{
matrix[i] = new int [3]; // Create inner array
for (int j = 0; j < matrix[i].Length; j++)
matrix[i][j] = i * 3 + j;
}
double[,] are called rectangular arrays, which are declared using commas to separate each dimension. The following piece of code declares a rectangular 3-by-3 two-dimensional array, initializing it with numbers from 0 to 8:
int [,] matrix = new int [3, 3];
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
matrix [i, j] = i * 3 + j;
double[,] is a 2d array (matrix) while double[][] is an array of arrays (jagged arrays) and the syntax is:
double[][] ServicePoint = new double[10][];
double[][] is an array of arrays and double[,] is a matrix. If you want to initialize an array of array, you will need to do this:
double[][] ServicePoint = new double[10][]
for(var i=0;i<ServicePoint.Length;i++)
ServicePoint[i] = new double[9];
Take in account that using arrays of arrays will let you have arrays of different lengths:
ServicePoint[0] = new double[10];
ServicePoint[1] = new double[3];
ServicePoint[2] = new double[5];
//and so on...