I'm reordering my dataTable columns using :
dataTable.Columns[int x].SetOrdinal(int y)
However, I use it for each column and that doesn't to work for me.
For instance :
dataTable.Columns[0].SetOrdinal(1);
dataTable.Columns[1].SetOrdinal(0);
Makes a double inversion...
And in my code, I have to define where each column must be.
Is there any solution to this ?
Thank you.
This process seems easy but not really such easy. The point is whenever you change the Ordinal of a column from x to a lower ordinal a (a < x) then all the columns with ordinals between a and x will be shifted right, if x is changed to a higher ordinal b (b > x) then all the columns with ordinals between x and b wil be shifted left. We must perform some update each time a column's ordinal is changed.
You can prepare a list of your column indices in the order you want, something like this:
List<int> indices = new List<int>{1,2,0,7,4,5,3,6};
for(int i = 0; i < indices.Count; i++){
dataTable.Columns[indices[i]].SetOrdinal(i);
if(indices[i] > i){
for(int j = i; j < indices.Count; j++)
if(indices[j] >= i && indices[j] < indices[i]) indices[j]++;//Right shifted
}
else if(indices[i] < i){
for(int j = i; j < indices.Count; j++)
if(indices[j] >= indices[i] && indices[j] < i) indices[j]--;//Left shifted
}
}
Or you can also prepare a list of your ColumnName in the order you want, something like this:
List<string> columns = new List<string>{"Column2","Column1","Column5","Column3","Column6","Column4"};
//The same code as above
You should change columns order in a loop from array of column name that each column name placed in correct order in array.
For more information go to this link : How to change DataTable columns order
Related
I am trying to create a 2D array from a DataTable, however Instead of getting the end result defined below. One row is not added, if that row is added, it will overwrite the column values.
Here is the end result I am looking to get:
[
//columns
['TaskID','TaskName','StartDate','EndDate','Duration','PercentComplete','Dependecies'],
//rows
['Cite','Create bibliography',null,1420649776903,1,20,'Research'], //missing row
['Complete','Hand in paper',null,1420908976903,1,0,'Cite,Write'],
['Outline','Outline paper',null,1420563376903,1,100,'Research'],
['Research','Find sources',1420390576903,1420476976903,null,100,null],
['Write','Write paper',null,1420822576903,3,25,'Research,Outline']
];
However, I get this.
[
["TaskID","TaskName","StartDate","EndDate","Duration","PercentComplete","Dependecies"],
["Complete","Hand in paper",null,1420908976903.0,1,0,"Cite,Write"],
["Outline","Outline paper",null,1420563376903.0,1,100,"Research"],
["Research","Find sources",1420390576903.0,1420476976903.0,null,100,null],
["Write","Write paper",null,1420822576903.0,3,25,"Research,Outline"]
]
I have tried:
// define the array size based on the datatable
object[,] multiDimensionalArry = new Object[breDataTable.Rows.Count, breDataTable.Columns.Count];
const int columnsArryIndex = 0;
// populate array with column names
if (breDataTable.Columns.Count > 0 && breDataTable.Rows.Count > 0)
{
// loop around columns
for (int i = 0; i <= breDataTable.Columns.Count - 1; i++)
{
// add all the column names
multiDimensionalArry[columnsArryIndex, i] = breDataTable.Columns[i].ColumnName;
}
}
// outer loop - loop backwards from the bottom to the top
// we want to exit the loop, when index == 0 as that is reserved for column names
for (int j = breDataTable.Rows.Count - 1; j >= 0; j--)
{
// get current row items array to loop through
var rowItem = breDataTable.Rows[j].ItemArray;
// inner loop - loop through current row items, and add to resulting multi dimensional array
for (int k = 0; k <= rowItem.Length - 1; k++)
{
multiDimensionalArry[j, k] = rowItem[k];
}
}
You're missing one row when creating your array since the columns name row dosent count as a row
object[,] multiDimensionalArry = new Object[breDataTable.Rows.Count + 1, breDataTable.Columns.Count];
And you need to change your for loop to take into count the extra row
// outer loop - loop backwards from the bottom to the top
// we want to exit the loop, when index == 0 as that is reserved for column names
for (int j = breDataTable.Rows.Count - 1; j >= 0; j--)
{
// get current row items array to loop through
var rowItem = breDataTable.Rows[j].ItemArray;
// inner loop - loop through current row items, and add to resulting multi dimensional array
for (int k = 0; k <= rowItem.Length - 1; k++)
{
multiDimensionalArry[j + 1, k] = rowItem[k];
}
}
Using Math.Net Numerics, how can I index parts of a matrix?
For example, I have a collection of ints and I want to get a submatrix with the rows and columns chosen accordingly.
A[2:3,2:3] should give me that 2 x 2 submatrix of A where the row index and the column index is either 2 or 3
Just use some thing like
var m = Matrix<double>.Build.Dense(6,4,(i,j) => 10*i + j);
m.Column(2); // [2,12,22,32,42,52]
to access the desired column use the Vector<double> Column(int columnIndex) extension method.
I suspect you were looking for something like this Extension method.
public static Matrix<double> Sub(this Matrix<double> m, int[] rows, int[] columns)
{
var output = Matrix<double>.Build.Dense(rows.Length, columns.Length);
for (int i = 0; i < rows.Length; i++)
{
for (int j = 0; j < columns.Length; j++)
{
output[i,j] = m[rows[i],columns[j]];
}
}
return output;
}
I've omitted the exception handling to ensure rows and columns are not null.
I have a 2-dimensional array with user-entered values. I need to find sum of the even elements in the diagonal of the array.
I know how to declare the array and get it filled by the user, but I'm not sure what even elements in the main diagonal really means.
I know I can find out if a number is even by saying:
if n / 2 == 0
Once I've reported the sum of the even elements in the diagonal, I would like to replace all 0 values in the array with ones.
Diagonal means all places where x and y cordinates are the same
Do if your array contains:
1 3 8 5
3 3 9 7
4 4 5 7
5 1 7 4
Then the diagonal are in bold.
Assuming the array is a square:
int sum = 0;
for(int i = 0; i < numOfArrayRows; i++)
{
//Use the mod operator to find if the value is even.
if(array[i][i] % 2 == 0)
sum += array[i][i];
//Change 0's to ones
for(int j = 0; j < numOfArrayCols; j++)
if(array[i][j] == 0)
array[i][j] = 1;
}
Also, next time add the "Homework" tag if you have a homework question :P
With a two-dimensional array it's really easy, since you don't need any index magic:
int a[N][N] = ...;
int sum = 0;
for(int i=0; i<N; ++i)
if(a[i][i] % 2 == 0) //or a[i] & 1, if you like, just check if it's dividable by 2
sum += a[i][i];
This C++ code shouldn't be that different in C or C#, but you should get the point. Likewise the second question would be as simple as:
int a[M][N] = ...;
for(i=0; i<M; ++i)
for(j=0; j<N; ++j)
if(a[i][j] == 0)
a[i][j] = 1;
And I suspec that the main diagonal is the one that begins with coordinates 0,0.
To replace 0 elements with 1 you would do something like:
if (array[i,j] == 0) array[i,j] == 1;
This sounds like homework - however I will help out :)
So if you have an 2D array, and in order to find the sum of the diagonal values, you will know that the indices of both of the values would match in order to provide you with each of the diagonal values.
To iterate through these you could use a simple loop that would sum up every diagonal value, as shown:
//Your Sum
int sum = 0;
//This will iterate and grab all of the diagonals
//You don't need to iterate through every element as you only need
//the diagonals.
for(int i = 0; i < sizeOfArray; i++)
{
//This will add the value of the first, second, ... diagonal value to your sum
sum += array[i,i];
}
To set each of the values that is 0 to 1, you could iterate through each element of the array and check if the value is 0, then set that value to 1, for example:
for(int i = 0; i < sizeOfArray; i++)
{
for(int j = 0; j < sizeOfArray; j++)
{
//Check if this value is 0;
//If it is 0, set it to 1, otherwise continue
}
}
int[,] array = new int[,] {{1,2,3},
{4,5,6},
{7,8,9}};
//Suppose you want to find 2,5,8
for(int row = 0; row < 3; row++)
{
for(int column = 0; column < 3; column++)
{
if((row == 0 && column == 1) || (row == 1 && column == 1) || (row == 2 && column == 1))
{
Console.WriteLine("Row: {0} Column: {1} Value: {2}",row + 1, column + 1, array[row, column]);
}
}
}
Here is the code you need, not much explain:
//Read the size of the array, you can get it from .Count() if you wish
int n = Convert.ToInt32(Console.ReadLine());
int[][] a = new int[n][];
//Reading all the values and preparing the array (a)
for (int a_i = 0; a_i < n; a_i++)
{
string[] a_temp = Console.ReadLine().Split(' ');
a[a_i] = Array.ConvertAll(a_temp, Int32.Parse);
}
//performing the operation (google what diagonal matrix means)
int PrimarySum = 0, SecondarySum = 0;
for (int i = 0; i < n; i++)
{
//The If condition is to skip the odd numbers
if (a[i][i] % 2 == 0) { PrimarySum += a[i][i]; }
//For the reverse order
int lastelement = a[i].Count() - 1 - i;
if (a[i][lastelement] % 2 == 0) { SecondarySum += a[i][lastelement]; }
}
//Get the absolute value
Console.WriteLine(Math.Abs(PrimarySum - SecondarySum).ToString());
Console.ReadKey();
Basically, I have a DataTable as below:
I want to run a method per element per row which has the parameters
AddProductPrice(SKU, Price, PriceBracket)
As an example...:
If we take the first row of data, the method will be run a potential of 16 times, once for each time Total Price X isn't null.
So for the first total price in the first row the call will be:
AddProductPrice(SKU, <Total Price 1 value>, 1)
Then for the second total price in the first row the call will be:
AddProductPrice(SKU, <Total Price 2 value>, 2)
Please note: for the National Selling element the call would be:
AddProductPrice(SKU, <National Selling value>, 16)
Is there a clever way to loop through each element in a DataRow to make the procedure more efficient?
For each row, looping through the columns and then finding the index of "Total Price", "National Selling" and adding product price accordingly.
for (int i = 0; i < dataTable.Rows.Count; i++)
{
DataRow myRow = dataTable.Rows[i];
for (int j = 0; j < dataTable.Columns.Count; j++)
{
if (dataTable.Columns[j].ColumnName.IndexOf("Total Price") > 0)
{
AddProductPrice(SKU, myRow.ItemArray[j], j);
}
else if (dataTable.Columns[j].ColumnName.IndexOf("National Selling") > 0)
{
AddProductPrice(SKU, myRow.ItemArray[j], 16); //
}
}
}
Loop through the DataTable.Columns Collection and parse based on the Column Name.
for(int i=0;i < dt.Columns.Count; i++)
{
if (dt.Columns[i].ColumnName.StartsWith("Total Price"))
{
var curBracket = Convert.ToInt32(dt.Columns[i].ColumnName.SubString(11));
AddProductPrice(SKU, curRow[dt.Columns[i].ColumnName, curBracket);
}
}
You can use the ItemArray (type object[]) property of DataRow and iterate through its elements from column tab.Columns.IndexOf("Trade Price 1") to tab.Columns.IndexOf("Trade Price 16").
Beware though, if the column order changes for some reason, your code could break. The safe way would be to iterate through items via an indexer - row["Trade Price " + i].
I am making a program that stores data in a 2D array. I would like to be able to delete rows from this array. I cannot figure out why this code doesn't work:
for (int n = index; n < a.GetUpperBound(1); ++n)
{
for (int i = 0; i < a.GetUpperBound(0); ++i)
{
a[i, n] = a[i, n + 1];
}
}
Could someone please help me out? I would like it to delete a single row and shuffle all the rows below it up one place. Thankyou!
you need to create a new array if you want to delete an item
try something like this
var arrayUpdated = new string[a.GetUpperBound(1)][a.GetUpperBound(0)-1];
for (int n = index; n < a.GetUpperBound(1); n++)
{
for (int i = 0; i < a.GetUpperBound(0); i++)
{
arrayUpdated [i, n] = a[i, 1];
}
}
The nested for loop method here works well: https://stackoverflow.com/a/8000574
Here's a method that converts the outer loop of the [,] array method above to use linq. Using linq here is only recommended if you are also doing other things with linq during the traversal.
public T[,] RemoveRow<T>(T[,] array2d, int rowToRemove)
{
var resultAsList = Enumerable
.Range(0, array2d.GetLength(0)) // select all the rows available
.Where(i => i != rowToRemove) // except for the one we don't want
.Select(i => // select the results as a string[]
{
T[] row = new T[array2d.GetLength(1)];
for (int column = 0; column < array2d.GetLength(1); column++)
{
row[column] = array2d[i, column];
}
return row;
}).ToList();
// convert List<string[]> to string[,].
return CreateRectangularArray(resultAsList); // CreateRectangularArray() can be copied from https://stackoverflow.com/a/9775057
}
used Enumerable.Range to iterate all rows as done in https://stackoverflow.com/a/18673845
Shouldn't ++i be i++? ++i increments before matrix operation is performed(ie pre-increment)