How do I convert a DataTable to a jagged array in C#? - c#

I'm new to C# and I can't find an example of this anywhere (although I have seen similar examples but the casting was ToString, whereas in my case I want arrays of integers). I have a DataTable object,
DataTable results = dbCon.ExecuteQuery("my query");
int m = results.Rows.Count;
int n = results.Columns.Count;
I want a jagged array consisting of n one-dimensional arrays (each array being a column of the DataTable (results, in this case).
int[][] jagged = new int[n][];
for (int i = 0; i < n; i++)
{
jagged[i] = new int[m];
//var coli = results.Columns.Cast<Array>().Select(column => Convert.ToInt32(column)).ToArray();
//jagged[i] = coli;
}
I've tried a few things (for example what I commented out) but I'm quite stuck now.
If anyone knows how to do this, please post something! Thanks!
Also, to be more specific, I'd really like to use a function like the one NumPy provides to Python... dataSet = np.array(dataList).astype('float'). Double for loops are not in my best interest as my DataTable is large.

I think you also need to make the array of type object. The DataTable DataRow holds things of type object, therefore that is what you need to store them as in your jagged array.
I think this will work:
DataTable table = dbCon.ExecuteQuery("my query");
int rowCount = table.Rows.Count;
int colCount = table.Columns.Count;
object[][] objs = new object[colCount][];
for (int currentColumn = 0; currentColumn < colCount; currentColumn++)
{
objs[currentColumn] = new object[rowCount];
for (int currentRow = 0; currentRow < rowCount; currentRow++)
{
objs[currentColumn][currentRow] = table.Rows[currentRow][currentColumn];
}
}

I think, you already have this. Try:
results.Rows[rowIndex][columnIndex]
To get it into jagged array, you may go for simple for loop:
for (int i = 0; i < results.Rows.Count; i++)
{
for (int j = 0; j < results.Columns.Count; j++)
{
jagged[i][j] = results.Rows[i][j];
}
}

You can get what you want just using LINQ against the DataTable. For each column in the DataTable, you need to iterate over the rows and select that column. You need to call Cast() to Select() on the columns and AsEnumerable() to be able to Select() on the rows:
int[][] jagged = results.Columns.Cast<DataColumn>()
.Select(
col => results.AsEnumerable()
.Select(row => row.Field<int>(col))
.ToArray()
).ToArray();

Related

How can I Store Datarow Values in 2d array in C#?

foreach (System.Data.DataRow drcount in dscount.Tables[0].Rows)
{
int strsample5 =drcount[0].ToString().Trim();
}
dscount is a dataset name and drcount is datarow name.datarow has values of dataset.I need to pass the values of datarow to a two dimensional array.How can I pass values to two dimensional array?
Try this, But, am not sure about your data. here strsample5 is an integer array. I think Its better to use Dictionary or List.
for (int i=0;i< dscount.Tables[0].Rows.Count;i++ )
{
for (int j = 0; j < dscount.Tables[0].Columns.Count; j++)
{
strsample5[i][j] = Convert.ToInt32(dscount.Tables[0].Rows[i][j].ToString());
}
}

Jagged 2D Array

I'm trying to create an array with the following structure
D
C C
B B B
A A A A
Which will be N x N but split diagonally. Initially, all I know is the bottom row essentially just:
string[,] table = new string[n,];
How can I build on this structure so that when I get to the next row I can declare how many elements it has? Would it be something along the lines of:
for(int i = 0; i <= n; i++) {
table[i] = new string[--n]
}
The [,] syntax creates multidimensional arrays, not jagged arrays. For the latter, you would need to do this:
int n = 4;
string[][] table = new string[n][];
for (int i = 0; i < n; i++)
table[i] = new string[n-i];
Btw. you really don’t want to decrement n while looping in a loop with the condition i < n (or i <= n).

How can I start initialization of "List of list" with columns

I have a list of list and I want to add values column oriented. Like in the following code sample:
Data = new List<List<double>>();
for (int i = 0; i < columnCount; i++)
{
for (int j = 0; j < rowCount; j++)
{
Data[j][i] = (probabilityList[j]) * K); // It won't work
}
}
I know it won't work because Data's index does not exist at current situation, and I need to use add() method.
However, I need to add values to list starts with columns:
[1 , null] ----> [1, null]
[null, null] [2, null]
How can I add values to a list of list starts with columns?
You need to create actual lists that you place inside your outer list of lists:
for (int i = 0; i < rowCount; i++)
{
Data.Add(new List<double>());
}
Once you've created all of the inner lists you can go through them and add values to them:
for (int i = 0; i < columnCount; i++)
{
for (int j = 0; j < rowCount; j++)
{
Data[j].Add((probabilityList[j]) * K);
}
}
Since you know the number of columns and rows you need you might think about using arrays instead of lists. When an array is initialized all members of the array are initialized to their default values. This would make your code
double[,] Data = new double[columnCount,rowCount];
for (int i = 0; i < columnCount - 1; i++)
{
for (int j = 0; j < rowCount - 1; j++)
{
Data[j,i] = (probabilityList[j]) * K);
}
}
You'll need to new up each element of the List of Lists
Data = new List<List<double>>();
for (int i = 0; i < columnCount; i++)
{
List<double> column = new List<double>();
for (int j = 0; j < rowCount; j++)
{
//not really sure if this is the correct code here
//that would depend on your logic
column.Add((probabilityList[j]) * K);
}
Data.Add(column);
}
A list is not an array. It does not have slots that you just put elements in, it's more like a chain.
So initially you have a List<List<double>> that is empty, it has no List<double> instances in it. You have to (explicitly) create and add those lists to the Data list.
Alternatively, if you do need row and columns with slots for elements, you could use a two-dimensional matrix, like this:
var matrixData = new double[rowCount, columnCount];
for (int i = 0; i < columnCount; i++)
{
for (int j = 0; j < rowCount; j++)
{
matrixData[j, i] = ((probabilityList[j]) * K);
}
}
A popular way to initialize a list of lists (List<List<T>>) with one line of code is to use LINQ as follows:
List<List<double>> Data = Enumerable.Range(0, columnCount).Select(i => new List<double>()).ToList();
This will produce a list of empty initialized lists of double type. From here every inner list can be accessed as Data[i] and elements can be added to it as Data[i].Add(double).
Here is a breakdown of what LINQ methods do to initialize a List<List<double> >
Enumerable.Range(0, columnCount)
Returns IEnumerable collection of Int with the columnCount number of members.
.Select(i => new List<double>())
For each of the element of the collection returned by the previous step runs a function "new List()" and stores output (initialized empty List of double) in IEnumerable collection (so we get IEnumerable<List<double>> with columnCount number of members).
.ToList();
Converts the collection in the step above IEnumerable<List<double>> to List<List<double> - the desired output.
In short: You have to initialize each collection of List<T> inside of your parent List<T> collection.
As you may know, initialization of collections is done throw keyword new in .NET Framework. Otherwise, all inner Lists will be Null and you would not be able to access them.
I have applied this concept to your code.
var mainData = new List<List<double>>();
for (int i = 0; i < columnCount; i++)
{
var innerList = new List<double>();
for (int j = 0; j < rowCount; j++)
{
innerList.Add((probabilityList[j]) * K);
}
mainData.Add(innerList);
}

Initializing two dimensional array of objects

I have a 2-dimensional array of objects, which I initialize using the traditional loop:
PairDS[,] tempPb1 = new PairDS[LoopCounterMaxValue+1, LoopCounterMaxValue+1];
for (int i = 0; i <= LoopCounterMaxValue; i++)
for (int j = 0; j <= LoopCounterMaxValue; j++)
tempPb1[i, j] = new PairDS();
Is there any better way to do this using Enumerable or something?
I thought Initialize could do it, but it only works with value types.
int N = 10;
PairDS[,] temp = new PairDS[N + 1, N + 1];
temp.Initialize();
What I recommend you do is use a jagged array.
class PairDS { public PairDS(int row, int col) { } }
static void Main(string[] args)
{
int N = 10;
PairDS[][] temp = Enumerable.Range(0, N + 1).Select(
(row) => Enumerable.Range(0, N + 1).Select(
(col) => new PairDS(row, col)).ToArray()).ToArray();
}
I don't believe you can represent a multi-dimensional array as an Enumerable or List, directly because it (the CLR) has no way of knowing how you intend to index the array.
If you did work it out row by row, it'd actually be worse (ie slower) then simply looping through the array as you're doing and initializing each cell.
There's no way to directly initialize a 2D array with the Enumerable types and as some users have pointed out there's nothing directly wrong with what you're doing. If you're just looking to simplify the loop though this might be what you're looking for;
const int length = LoopCounterMaxValue + 1;
PairDS[,] tempPb1 = new PairDS[length, lenth];
for (var i = 0; i < length * length; i++) {
var column = i % length;
var row = (i - column) / length;
tempPb1[row, column] = new PairDS();
}

How to add DataRow in string of arrray

In the DataTable i have n number rows want add those rows in array?
DataTable tbl = new DataTable();
tbl.Rows
Rows is array of your records...
The code below stores all the information in a datatable in a double array of strings. The code should be plug-and-play, just make sure you swap out "dataTable1" with the name of your actual DataTable.
string[,] stringArray = new string[dataTable1.Rows.Count, dataTable1.Columns.Count];
for (int row = 0; row < dataTable1.Rows.Count; ++row)
{
for (int col = 0; col < dataTable1.Columns.Count; col++)
{
stringArray[row, col] = dataTable1.Rows[row][col].ToString();
}
}
To access the first item out of stringArray, simply use call the code below, using the indices as you would for a normal array.
stringArray[0, 0]

Categories

Resources