How to Convert 2D List to 2D Array in C# - c#

I have the following C# List:
List<Response> listAllData = new List<Response>();
listAllData.Add(new Response() {
strId = propResponse.strId,
strName = propResponse.strName
});
And then I am converting it to an array as such:
object[] array2 = listAllData.ToArray();
But when I'm trying to write data to a range using:
rngValues.Value = array2;
I'm getting an error
Exception from HRESULT: 0x800A03EC
I am (reasonably) certain this is b/c the resulting array2 is not actually a 2D multidimensional array, but instead an array-of-arrays.
So my question is... How do I get my listAllData into a 2D array?
It is not a "jagged array" meaning there are always 2 elements in each entry.

resulting array2 is not actually a 2D multidimensional array, but instead an array-of-arrays.
No, it's a 1-D array of Response objects. If you want it in a 2-D array of objects (where the row is the two string properties from the source object) you'll have to build a loop (Linq does not support 2-D arrays):
object[,] array2 = new object[listAllData.Count,2];
for(int i = 0; i < listAllData.Count; i++)
{
array2[i,0] = listAllData[i].strId;
array2[i,1] = listAllData[i].strName;
}

Related

Why can't I create a multidimensional array of arrays?

My program involves a 2-dimensional board: Square[width,height]. Each Square contains a collection of Pieces.
In the presentation layer, I want to only present the collection of Pieces in each Square and represent each Piece with its string Name. I.e. string[][width,height].
Declaring string[][,] compiles with no problem but I can't initialize the variable:
string[][,] multiArrayOfArrays; //No problemo
multiArrayOfArrays = new string[][8,8]; //Generates errors
The following errors are generated for the second line:
CS1586 Array creation must have array size or array initializer
CS0178 Invalid rank specifier: expected ',' or ']' ModChess
CS0178 Invalid rank specifier: expected ',' or ']' ModChess
I'm currently using List<string>[,] as a workaround but the errors vex me. Why can I successfully declare a string[][,] but not initialize it?
Note: Using VS Community 16.0.4, C# 7.3.
string[][,] multiArrayOfArrays; //No problemo
Here you just declare variable of specific type.
multiArrayOfArrays = new string[][8,8]; //Generates errors
And here you actually create new object of specific type. It generates errors because this is invalid syntax for multidimentional array initialization.
You need to specify size for first dimension [] and then initialize each element of that array with string[,].
Think of it as array of arrays:
string[][,] multiArrayOfArrays; //No problemo
multiArrayOfArrays = new string[5][,];//create 5 elements of string[,] array
for (int i = 0; i < multiArrayOfArrays.Length; ++i)
{
multiArrayOfArrays[i] = new string[8,8];//actually fill elements with string[8,8]
}
or
string[][,] multiArrayOfArrays; //No problemo
multiArrayOfArrays = new string[][,]
{
new string[8,8],
new string[8,8],
new string[8,8],
};
Probably you want a string[,][] a.
string[,][] a = new string[3, 4][];
a[0, 0] = new string[10];
a[0, 1] = new string[4];
a[1, 0] = new string[6];
string s = a[0, 0][2];
You have a special case of a jagged array, where the first array is 2-dimensional. It contains one-dimensional arrays of different sizes as elements.
The ordering of the array brackets might seem wrong, as the element type is usually on the left side of the brackets; however, if you think about on how you want to access elements, then it makes sense. First, you want to specify the 2 coordinates of the 2-dimensional board, then the single index of the pieces collection.
According to Jagged Arrays (C# Programming Guide), int[][,] jaggedArray4 = new int[3][,] "... is a declaration and initialization of a single-dimensional jagged array that contains three two-dimensional array elements of different sizes."

how to get length of string [] []

I have 2D array of string defined as
string[][] input_data;
I can count the number of rows by input_data.GetLength(0)
but if I use input_data.GetLength(1) to get number of column, I always get
System.IndexOutOfRangeException was unhandled
Message=Index was outside the bounds of the array.
Source=mscorlib
StackTrace:
at System.Array.GetLength(Int32 dimension)
...
I also noticed that at debugging, when I hover my mouse on my array (after all the data has been inserted) it only shows the first value (number of row) like this: input_data| {string[18][]}, if I continue expand the array then it shows all the 18 row data with the column data, like this:
How do I get the number of column? (in this case it is 139)
What you posted is a jagged array, not a multi-dimensional array. It's a 1-D array that contains other arrays. There is no second dimension so you can't use data.GetLength(1). Each row can have a different number of columns.
You can get the minimum or maximum number of columns for each row with data.Max(r=>r.Length) or data.Min(r=>r.Length), eg:
var s=new string[][]{
new[] {"a","b"},
new[] {"a"}
};
Console.WriteLine("{0} {1}",s.Max(r=>r.Length),s.Min(r=>r.Length));
will print
2 1
To specify a multi-dimensional array, you need to use the [,] syntax:
var s=new string[,]{
{"a","b"},
{"c","d"},
{"e","f"}
};
Console.WriteLine("{0} {1}",s.GetLength(0),s.GetLength(1));
This will return :
3 2
GetLength(1) would work if you had a multidimensional array:
string[,] input_data = new string[27,139];
var columns = input_data.GetLength(1);
What you have now is a jagged array not a 2D array, so there is no guarantee that all items ('rows') have the same number of elements ('columns').
However in case you can't use multidimensional array for some reason and you are sure that the input will be that way you can use the length of the first element input_data[0].Length
I think you are confusing an array of arrays and a multi dimentional array, run this code :
string[][] array_of_arrays = new string[5][];
Console.WriteLine(array_of_arrays.Length);
array_of_arrays[0] = new string[5];
array_of_arrays[1] = new string[6];
Console.WriteLine(array_of_arrays[0].Length);
Console.WriteLine(array_of_arrays[1].Length);
string[,] multi_d_array = new string[4,2];
Console.WriteLine(multi_d_array.GetLength(0));
Console.WriteLine(multi_d_array.GetLength(1));
This is a jagged array. You can get the first dimensions size as 'input_data.GetLength(0)' and second dimension size as 'input_data.GetLength(1)'. Try it
Example:
string[,] input_data = new string[5,12];
var column1 = input_data.GetLength(0);
var column2 = input_data.GetLength(1);

Get one dimensionial array from a mutlidimensional array in c#

I have a two dimensional array like this:
decimal[,] dataArray;
dataArray = new decimal[10, 20];
How can I get an onedimesional array that contains the values from one particular column?
Thanks.
There is no built-in API for slicing multidimensional arrays. Write a loop that goes through all rows, and harvests a specific column into a result array, or use LINQ to "fold" the loop:
var col = Enumerable.Range(0, 20).Select(r=>dataArray[3, r]).ToArray();

How can I change an 2D array to a 2D list and then back to a 2D array again?

I thought searching SO would show me a hit regarding 2D lists to 2D arrays but it seems it's not as common as I had thought.
This is what I've got:
// init array
int[][] a = new int[10][10];
// change 2D array to 2D list
List<List<int>> b = a.Cast<List<int>>().ToList();
// change 2D list back to 2D array
???
How can I change b back to a 2D array? Also is the above correct?
Something like this:
List<List<int>> lists = arrays.Select(inner=>inner.ToList()).ToList();
int[][] arrays = lists.Select(inner=>inner.ToArray()).ToArray();
It's totally wrong. You can't get b in that way. And even the initialization is wrong. And in .NET there are two types of multidimensional arrays... True multidimensional arrays and jagged arrays...
Let's start... You are using a jagged array (I won't tell you what it's, or the difference, you didn't ask for it... if you need them, google for it)
int[][] a = new int[10][]; // see how you define it?
// Only the first dimension can be is sized here.
for (int i = 0; i < a.Length; i++)
{
// For each element, create a subarray
// (each element is a row in a 2d array, so this is a row of 10 columns)
a[i] = new int[10];
}
Now you have defined a 10x10 array jagged array.
Now a little LINQ:
You want a list:
List<List<int>> b = a.Select(row => row.ToList()).ToList();
you want back an array:
int[][] c = b.Select(row => row.ToArray()).ToArray();
The first expression means
foreach element of a, we call this element row `a.Select(row =>` <br>
make of this element a List `row.ToList()` and return it<br>
of all the results of all the elements of a, make a List `.ToList();`
The second is specular.
Now... Just out of curiosity, and if you had a true multidimensional array? then it was complex, very comples.
int[,] a = new int[10,10];
int l0 = a.GetLength(0);
int l1 = a.GetLength(1);
var b = new List<List<int>>(
Enumerable.Range(0, l0)
.Select(p => new List<int>(
Enumerable.Range(0, l1)
.Select(q => a[p, q]))));
var c = new int[b.Count, b[0].Count];
for (int i = 0; i < b.Count; i++)
{
for (int j = 0; j < b[i].Count; j++)
{
c[i, j] = b[i][j];
}
}
With a tricky (and horrible) LINQ expression we can "convert" a multidimensional array to a List<List<int>>. The road back isn't easily doable with LINQ (unless you want to use the List<T>.ForEach() that you shouldn't ever use, because it's not kosher, and then List<T>.ForEach() isn't LINQ)... But it's easily doable with two nested for ()

How to pass part of a two-dimensional array as parameter to a function?

I've got a two-dimensional array like this:
double[,] results = new double[100,100];
I'd like to pass every one dimensional part of the array to a function as a paremeter.
for (int i = 0; i < 100; i++){
cool_function (results[???], 10);
}
How do I do this in C#?
source
Jagged arrays are arrays of arrays. The elements of a jagged array are other arrays.
Declaring Jagged Arrays
Declaration of a jagged array involves two brackets. For example, the following code snippet declares a jagged array that has three items of an array.
int[][] intJaggedArray = new int[3][];
The following code snippet declares a jagged array that has two items of an array.
string[][] stringJaggedArray = new string[2][];
Initializing Jagged Arrays
Before a jagged array can be used, its items must be initialized. The following code snippet initializes a jagged array; the first item with an array of integers that has two integers, second item with an array of integers that has 4 integers, and a third item with an array of integers that has 6 integers.
// Initializing jagged arrays
intJaggedArray[0] = new int[2];
intJaggedArray[1] = new int[4];
intJaggedArray[2] = new int[6];
We can also initialize a jagged array's items by providing the values of the array's items. The following code snippet initializes item an array's items directly during the declaration.
// Initializing jagged arrays
intJaggedArray[0] = new int[2]{2, 12};
intJaggedArray[1] = new int[4]{4, 14, 24, 34};
intJaggedArray[2] = new int[6] {6, 16, 26, 36, 46, 56 };
You can't do it without copying the corresponding part of the array.
Otherwise, you can use a double[][]. To initialize:
double[][] results = new double[100][];
for(int i = 0; i < 100; i++)
results[i] = new double[100];
You could do this by using a jagged array Type[][] instead of Type[,]. In this case you can just pass array[index]. Otherwise you will have to either pass the two-dimensional array together with the index of the subarray of interest and perform the indexing in the called method or create a copy of the subarray of interest.
If you mean for an array myarray[x][y] that you want to call a function for x arrays of size y then all you need is the following code:
int i;
for (i = 0; i < 100; i++)
{
cool_function(array[i], 10);
}

Categories