I'm trying to build a multi-dimensional array to store integer arrays.
Array[] TestArray = new Array[2];
for(int i = 0; i < TestArray.Length; i++)
{
TestArray[i] = new int[5];
}
How do I go about accessing the newly created members of the Array? I am not sure how to access the newly created arrays in the array although I can see that they're properly created and stored when debugging in Visual Studio.
If you want an array of integer arrays, then you should declare it as such:
int[][] testArray = new int[2][];
for(int i = 0; i < testArray.Length; i++)
{
testArray[i] = new int[5];
}
Arrays of arrays are called Jagged Arrays (in contrast to Multidimensional Arrays).
Here is how to access fourth item in the second array:
int value = ((int[]) TestArray.GetValue(1))[3];
Although you would have much less trouble working with jagged arrays:
int[][] TestArray = new int[2][];
for (int i = 0; i < TestArray.Length; i++)
{
TestArray[i] = new int[5];
}
or multidimensional arrays:
int[,] TestArray = new int[2,5];
Cast the TestArray element as an int[].
Array[] TestArray = new Array[2];
for(int i = 0; i < TestArray.Length; i++)
{
TestArray[i] = new [] { 2,3 };
}
var firstIndexOfFirstArray = ((int[])TestArray[0])[0];
T[][] is the syntax you are looking for.
int[][] test = new int[2][]; //Declaring the array of arrays.
for (int i = 0; i < test.Length; i++)
{
test[i] = new int[5]; //Instantiating a sub-arrays.
for (int x = 0; x < test[i].Length; x++)
test[i][x] = x + i; //Filling a sub-arrays.
}
foreach (var array in test) //iterating over the array of arrays.
Console.WriteLine("Array: " + string.Join(", ", array)); //using a sub-array
Console.ReadLine();
For more info: http://msdn.microsoft.com/en-us/library/2s05feca.aspx
If looking for integer array, try
int[][] testArray
Related
This question already has answers here:
Converting jagged array to 2D array C#
(4 answers)
Closed 3 years ago.
I am converting a list within a list to an int[][] using:
int[][] preConvertInts = processedList.Select(array => array.ToArray().ToArray()) as int[][];
I am returning an int[,] in my method. What is the best way to convert an int[][] to an int[,]?
Edit: method
public static int[,] GetIntArrayInts(string dataString){
string data = dataString;
data = data.Replace(Environment.NewLine, "\n");
List<List<int>> processedList = new List<List<int>>();
string[] rows = data.Split('\n');
foreach (string row in rows){
string[] columns = row.Split(',');
List<int> ints = new List<int>();
foreach (string column in columns){
if (int.TryParse(column, out int tileGid)) ints.Add(tileGid);
}
processedList.Add(ints);
}
int[][] preConvertInts = processedList.Select(array => array.ToArray().ToArray()) as int[][];
int[,] processedIntArray = new int[preConvertInts[0].Length, preConvertInts[1].Length];
for (int i = 0; i < preConvertInts.Length; i++){
int[] intArray = preConvertInts[i];
for (int j = 0; j < intArray.Length; j++){
processedIntArray[i, j] = preConvertInts[i][j];
}
}
return processedIntArray;
}
What is the best way to convert an int[][] to an int[,]?
it is the one that is described in this post. Yours will actually also work if all sub-arrays have the same Length. But to cite you:
Unfortunately, my array is not rectangular. – Luna
Then it would not make much sense to try to convert it. Unless you loose values or you add values to make the dimensions of all sub arrays equal.
But your problem in the code is not this conversion but this one:
I am converting a list within a list to an int[][] using:
int[][] preConvertInts = processedList.Select(array => array.ToArray().ToArray()) as int[][];
This is wrong. You will get null for preConvertInts! if you check the return value of the Select call:
You can see that it returns IEnumerable<int[]> and not int[][]. Casting it with as int[][]; does not work and masks only the fact that the 2 types are different from the compiler. What you do there is to convert each sublist into an array and then convert (the already converted array) simply again into an array.
You need to make the select in the proper way:
int [][] preConvertInts = processedList.Select(x=>x.ToArray()).ToArray();
Explanation:
1) in the first step you collect all sublists and convert each one into an array: Select(x=>x.ToArray())
2) now this call returns an IEnumerable<int[]> which you need to convert again to an array:
Select(x=>x.ToArray()).ToArray();
^^
||
note the dot behind the closing parentesis of the Select call
Jagged Array
public static T[,] ToMultiArray<T>(this IList<T[]> arrays)
{
var length = arrays[0].Length;
var result = new T[arrays.Count, length];
for (var i = 0; i < arrays.Count; i++)
{
var array = arrays[i];
if (array.Length != length)
{
throw new ArgumentException("Misaligned arrays");
}
for (var j = 0; j < length; j++)
{
result[i, j] = array[j];
}
}
return result;
}
Multidimensional Array
public static T[][] ToJaggedArray<T>(this IList<T[]> arrays)
{
var result = new T[arrays.Count][];
for (var i = 0; i < arrays.Count; i++)
{
var array = arrays[i];
var length = array.Length;
result[i] = new T[length];
for (var j = 0; j < length; j++)
{
result[i][j] = array[j];
}
}
return result;
}
Usage
var preConvertInts = list.ToJaggedArray();
or
var preConvertInts = list.ToMultiArray();
Update
this IList<T[]> arrays this method is for lists which contain arrays,
to fit OP's example it should be (this IList<List<T>> arrays) – Mong
Zhu
Jagged Array
public static T[][] ToJaggedArray<T>(IList<List<T>> arrays)
{
var result = new T[arrays.Count][];
for (var i = 0; i < arrays.Count; i++)
{
var array = arrays[i];
var length = array.Count;
result[i] = new T[length];
for (var j = 0; j < length; j++)
{
result[i][j] = array[j];
}
}
return result;
}
Multidimensional Array
public static T[,] ToMultiArray<T>(IList<List<T>> arrays)
{
var length = arrays[0].Count;
var result = new T[arrays.Count, length];
for (var i = 0; i < arrays.Count; i++)
{
var array = arrays[i];
if (array.Count != length)
{
throw new ArgumentException("Misaligned arrays");
}
for (var j = 0; j < length; j++)
{
result[i, j] = array[j];
}
}
return result;
}
Note : Totally untested
I need to create an array for which I do not know the size in advance. I used the following, but it gives an index out of bounds error in my for -loop.
string[] arr = s.Split('\n');
int[] indices = new int[arr.Length];
string[][] new_arr = new string[arr.Length][];
for (int i = 0; i < arr.Length; i++)
{
if (arr[i].StartsWith("21"))
{
indices[i] = i;
}
}
indices = indices.Where(val => val != 0).ToArray(); //contains indices of records beginning with 21
for (int i = 0; i < indices.Length - 1; i++)
{
new_arr[0][i] = arr[i];
} //first n elements
The error is in the second for-loop. It says
Object reference not set to an instance of an object.
But I did instantiate the string at the beginning?
You just need to initialize each of the arrays within the jagged array:
indices = indices.Where(val => val != 0).ToArray(); //contains indices of records beginning with 21
// create second-level array
new_arr[0] = new string[indices.Length] ;
for (int i = 0; i < indices.Length - 1; i++)
{
new_arr[0][i] = arr[i]; // why 0 here?
}
For a 2 dimensional array, you will have to specify the size of the first dimension. As I see your code, it is using what is called the jagged array (array containing array as elements) and not a pure 2 dimensional array.
var array1 = new int[2,10]; // this is a 2 dimensional array
var array2 = new int[2][]; // this is an array of 2 elements where each element is an `int[]`
As you notice, we don't need to specify the size of the inside element int[]
Now you understand the jagged array, you can see that you are not initializing the inside element, but simply accessing it - and since it is null by default, you hit the exception.
for (int i = 0; i < indices.Length - 1; i++)
{
new_arr[0][i] = arr[i];
} //first n elements
In the code above, you should have new_arr[i][0] = arr[i] and also before that line you need to do new_arr[i] = new int[x] where x is teh size that you want for the inside array.
string[][] myArray = new[size][];
for(int i=0;i<2;i++){
myArray[i][0] = newValue.toString();
}
While assigning the values i get an error
I get the Object Reference not set to instance of object exception. Please help
You have created a jagged array of strings. The outermost array has been initialized to size elements, but that means there are size spaces each for a string[], each of which is currently null. You need to create the inner arrays, or create a rectangular array.
Based on the poor code, it should be something like this:
string[][] myArray = new string[size][];
for (int j = 0; j < myArray.Length; j++) {
myArray[j] = new string[3];
for (int i = 0; i < myArray[j].Length; i++) {
myArray[j][i] = newValue.ToString();
}
}
Try this
int dim1 = 2;
int dim2 = 1;
string[,] iii = new string[dim1, dim2];
for (int i = 0; i < iii.GetLength(0); i++)
{
iii[i, 0] = "myValue";
}
I'm trying to convert a two dimensional string array to a two dimensional int array:
int[][] inner = new int[4][];
string[][] arr = new string[4][]
{
new string[] {"11"},
new string[] {"12"},
new string[] {"21"},
new string[] {"22"}
};
for (int i = 0; i < arr.Length; i++)
{
string name = string.Join(".", arr[i]);
for (int j = 0; j < name.Length; j++)
{
inner[i][j] = Convert.ToInt32(name.Substring(j,1));
}
}
But I'm getting the following exception:
Object reference not set to an instance of an object
at:
inner[i][j] = Convert.ToInt32(name.Substring(j,1));
Change the declaration of your "inner" variable to
int[,] inner = new int[4,2];
I can't seem to figure out how to work with Jagged Arrays and Files. I have three files with numbers in them and wan to read each file into its own array. This is what I have so far. Was trying to populate the [0] array but to no avail. Any help appreciated. Can't find any tutorials on doing this, either.
private void button1_Click(object sender, EventArgs e)
{
StreamWriter section1;
StreamWriter section2;
StreamWriter section3;
StreamReader section1read;
StreamReader section2read;
StreamReader section3read;
section1 = File.CreateText("Section1.txt");
section2 = File.CreateText("Section2.txt");
section3 = File.CreateText("Section3.txt");
int[][] Scores = new int[3][];
Random randnum = new Random();
for (int i = 0; i < 12; ++i)
{
int num = randnum.Next(55, 99);
section1.WriteLine(num);
}
for (int j = 0; j < 8; ++j)
{
int num1 = randnum.Next(55, 99);
section2.WriteLine(num1);
}
for (int k = 0; k < 10; ++k)
{
int num3 = randnum.Next(55, 99);
section3.WriteLine(num3);
}
section1.Close();
section2.Close();
section3.Close();
section1read = File.OpenText("Section1.txt");
int nums = 0;
while (!section1read.EndOfStream)
{
Scores[0][nums] = int.Parse(section1read.ReadLine());
++nums;
}
for (int i = 0; i < Scores.Length; ++i)
{
listBox1.Items.Add(Scores[0][i]);
}
section1read.Close();
}
Jagged arrays should be initialized in two steps:
The array itself:
int[][] Scores = new int[3][];
The sub-arrays:
Scores[0] = new int[12];
Scores[1] = new int[8];
Scores[2] = new int[10];
Array is a fixed length data structure. If you don't know the size in advance, you have to use a dynamic length structure. The best option is List<> class:
List<List<int>> scores = new List<List<int>>();
scores.Add( new List<int>() );
using( StreamReader section1read = File.OpenText("Section1.txt"))
{
string line;
while ((line = section1read.ReadLine()) != null)
{
scores[0].Add(int.Parse(line));
}
}
Here are other things to consider:
Use a using block make sure any unmanaged resources associated with file is disposes.
You can check the return value of StreamReader.ReadLine() to determine the end of file
http://msdn.microsoft.com/en-us/library/2s05feca.aspx
Quote:
"Before you can use jaggedArray, its elements must be initialized. You can initialize the elements like this:
jaggedArray[0] = new int[5];
jaggedArray[1] = new int[4];
jaggedArray[2] = new int[2];"
So, what you're doing in your code is initializing a jagged array of three int[]s that are all set to null. If you don't create the array at each index before attempting to assign to it, nothing is there.
It seems what you want, though, is dynamic allocation - you don't know how many integers you need to store when you wrote the program. In this case, you should learn about the class List<>. List<> is like an array except you can add to and remove from the number of elements it has at runtime, rather than declaring it has a fixed size, using Add and Remove. http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx