I have a string containing numbers as a 2D matrix. I'm trying to use Split function to split the contents of a string into an array. So, when I do:
String[] subStrs = new String[20];
subStrs = str.Split('\n');
The code above works fine. However, when I try to create a 2D array and try to populate sub-arrays using the same way:
String[,] numbers = new String[20,20];
for (int i = 0; i < subStrs.Length; i++ )
{
numbers[i] = subStrs[i].Split(' '); //Error
}
I get the following compiler error:
Wrong number of indices inside []; expected 2.
If 2D array is really an array of arrays, then why is the statement numbers[i] = subStrs[i].Split(' '); illegal?
PS : I do know that I can use a nested loop instead to populate numbers. I'm just curious why can't I use the above method?
If 2D array is really an array of arrays
It's not. A 2D array is just that, a 2D array.
An array of arrays is an array of arrays:
string[][]
If you have an array of arrays, then the item at each index of the outer array is another array. If you have a 2D array then both dimensions are needed to get at a value, which is itself the value of the array, not another dimension.
Related
I have an Array where i want to know each array length.
public int[][,] _EnemyPosition = new int[][,]
{
new int[,]{ {0},{1},{2},{3},{4}},
new int[,]{ {0,6},{1,7},{2,8},{3,9},{4,10}},
};
Debug.Log(_EnemyPosition.Length); // Output is 2
Debug.Log(_EnemyPosition[1].GetLength(0)); // Output is 5
But i am not able to get
Debug.Log(_EnemyPosition[1][0].length);
Its throw me an error
error CS0022: Wrong number of indexes `1' inside [], expected `2'
i want to know how to get length of this array
_EnemyPosition[1][0].length
var length = _EnemyPosition[0].Length; //returns 5 (5·1)
var length = _EnemyPosition[1].Length; //returns 10 (5·2)
Is that what you want? Your requirement is far from clear:
i want to know how to get length of this array: _EnemyPosition[1][0].length
That is not an array, _EnemyPostion[1] is a two dimensional array [,]. Consider the following analogue scenario:
int[,] myTwoDimensionalArray = ...
var whatever = myTwoDimensionalArray[0]; //not valid, array dimensiones don't match.
So, we have three options when it comes to the length you want returned:
_EnemyPosition[1].Length which returns the total length of the two dimensional array 10.
_EnemyPosition[1].GetLength(0) which returns the length of the first dimension of the two dimensional array 5
_EnemyPosition[1].GetLength(1) which returns the length of the second dimension of the two dimensional array 2
And obviously the result of 2 times 3 is 1. So, which one do you want?
Let's disentangle the arrays: you have
int[][,] _EnemyPosition
which is an array of 2d arrays; so you can call
_EnemyPosition.Length
which is number of 2d arrays in total; for each 2d array at index position you can call
_EnemyPosition[index].GetLength(0)
_EnemyPosition[index].GetLength(1)
which are the lengths of each dimensions (lines and columns) within indexs 2d array. Please notice, that jagged array and 2d array are different types; that's why you can't put
// doesn't compile
_EnemyPosition[1][0]
since _EnemyPosition[1] returns 2d array which wants 2 indexes (something like _EnemyPosition[1][0,1])
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.
EG.
String [ ][ ] LinesSplitByComma1 =
File.ReadAllLines("Filepath").Select(s => s.Split(',')).ToArray();
An array of arrays of strings.
It's reading a file and creating an array where each element is a line from the file, represented by an array of strings created by splitting that line at commas.
So a file like
a,b,c
1,2,3
asdas,ertert,xcvxcvx
Would be represented as
LinesSplitByComma1[0][0] = "a"
LinesSplitByComma1[0][1] = "b"
LinesSplitByComma1[0][2] = "c"
LinesSplitByComma1[1][0] = "1"
LinesSplitByComma1[1][1] = "2"
LinesSplitByComma1[1][2] = "3"
LinesSplitByComma1[2][0] = "asdas"
LinesSplitByComma1[2][1] = "ertert"
LinesSplitByComma1[2][2] = "xcvxcvx"
This is an array of string arrays. In your specific case, you have an array of lines, each of which is split into an array of comma-separated tokens.
string[][] lines = File.ReadAllLines("Filepath").Select(s => s.Split(',')).ToArray();
string[] tokens = lines[i];
string token = tokens[j];
This is a "jagged" array; an array of arrays of strings. It is one form of "two-dimensional array"; the other is a "rectangular array" which can be declared like string[,].
The difference is inherent in the name; a jagged array's sub-arrays can each have a different number of values, while a rectangular array's sub-arrays are each the same length.
In memory, they look very different. A jagged array is initially created as an array of "pointers" to other arrays, and as the jagged array is initialized, the arrays that form the second dimension of the construct are each individually created and referenced in the "buckets" of the first-dimension array:
string[][] jaggedArray = new string[3][]; //the first dimension contains three elements
jaggedArray[0] = new string[5]; //now the first element is an array of 5 elements.
jaggedArray[1] = new string[4]; //the second element's array can be a different length.
jaggedArray[0][2] = "Test";
var secondDim = jaggedArray[1]; //A higher-dimension array of a jagged array can be independently referenced.
A rectangular array, however, is created at one time as a single block of memory:
string[,] rectArray = new string[3,5]; //the entire 3x5 block of string refs is now reserved.
rectArray[0,4] = "Test"; //we didn't have to declare the second-dimension array.
//However, the following will not compile:
var secondDim = rectArray[1]; //a rectangular array's higher dimensions can't be "severed".
I've created a multidimensional array and want to set the entire inner array equal to a separate (single dimensional) array. How can I do this, besides going through each position in the arrays and setting grid[row][val] = inputNums[val]?
int[,] grid = new int[20,20];
// read a row of space-deliminated integers, split it into its components
// then add it to my grid
string rowInput = "";
for (int row = 0; (rowInput = problemInput.ReadLine()) != null; row++) {
int[] inputNums = Array.ConvertAll(rowInput.Split(' '), (value) => Convert.ToInt32(value))
grid.SetValue(inputNums , row); // THIS LINE DOESN'T WORK
}
The specific error I'm getting is:
"Arguement Exception Handled: Array was not a one-dimensional array."
You are mixing "jagged" arrays (arrays of arrays) with multidimensional arrays. What you want to use is probably jagged arrays (because no one in his right mind would want to use md arrays :-) )
int[][] grid = new int[20][];
// ...
grid[row] = inputNums;
// access it with
grid[row][col] = ...
// columns of a row:
var cols = grid[row].Length;
// number of rows:
var rows = grid.Length;
A md array is a single monolithical "object" with many cells. Arrays of arrays are instead many objects: for a 2d jagged array, one object is for the row "structure" (the external container) and one is for each "row". So in the end with a jagged array you must do a single new int[20, 20], with a jagged array you must do a new int[20][] that will create 20 rows and 20 myArray[x] = new int[20] (with x = 0...19) one for each row. Ah... I was forgetting: a jagged array can be "jagged": each "row" can have a different number of "columns". (everything I told you is valid even for 3d and *d arrays :-) You only have to scale it up)
I need to declare 3d array variable but can't.
int[][][] ary = new int[5][2][];
ary[0,0] = new int[20];
ary[0,1] = new int[3];
Could you please help me!
Thanks in advance
Hamid
int[,][] ary = new int[5,2][];
declares a 2D array of int[] objects and initializes it. Use
ary[0, 0] = new int[10];
ary[0, 0][0] = 42;
to access elements.
Note that in C#, multidimensional arrays are different from arrays of arrays. That is, int[][][] is a single dimensional array of single dimensional arrays of single dimensional arrays of integers while int[,,] is a three dimensional array of integers.