I have DataTable and i need to clear all empty columns. So here is code example:
for (var i = 0; i < table.Columns.Count; i++)
{
if (table.Rows.Cast<DataRow>().All(r => string.IsNullOrWhiteSpace(r[i].ToStringOrNull())))
{
table.Columns.RemoveAt(i--);
}
}
Question : How can i get row Number in If-statement ?
Thanks.
If by "row number", you mean the index of a Row object in the Rows collection, then you can't get that directly from the Row object. You can, as suggested in Vlad's comment, use something like this instead:
for (var i = 0; i < table.Columns.Count; i++)
{
if (Enumerable.Range(0, table.Rows.Count).All(
j => string.IsNullOrWhiteSpace(tables.Rows[j][i].ToStringOrNull())))
{
table.Columns.RemoveAt(i--);
}
}
That said, it seems to me that it would be better to process the data such that you visit each row only once. This should at the very least improve data locality, and in some scenarios could significantly improve performance. E.g.:
bool[] keepColumn = new bool[table.Columns.Count];
for (int i = 0; i < table.Rows.Count; i++)
{
for (int j = 0; j < table.Columns.Count; j++)
{
if (!keepColumn[j] &&
!string.IsNullOrWhiteSpace(table.Columns[j].ToStringOrNull()))
{
keepColumn[j] = true;
}
}
}
for (int i = table.Columns.Count - 1; i >= 0; i--)
{
if (!keepColumn[i])
{
table.Columns.RemoveAt(i);
}
}
It's obviously a bit more verbose, but IMHO it would be worth it in this case, because it's processing the data in their natural organization (i.e. tables are naturally rows that have columns, as opposed to columns that have rows).
Related
Hello I have created a program that the user imputs the values of a 2D array 6x6 and show it now I have to make a new metod i guess to rotate the elements from rows 0,2,4 put them in colums 1,3,5 and elements from rows 1,3,5 putting them in colums 0,2,4 than tell how many "M" are in total at the two last rows". can someone tell me how to do that i have no idea. Thanks
This is a photo of my code and another photo how should i change the indexes
The Solution is written in java hope you get the idea.
public class ProgramMain {
public static void main(String[] args) {
int[][] arr = {
{0,0,0,0,0,0},
{1,1,1,1,1,1},
{2,2,2,2,2,2},
{3,3,3,3,3,3},
{4,4,4,4,4,4},
{5,5,5,5,5,5}
};
int[][] output = new int [6][6];
// elements from rows 0,2,4 put them in column 1,3,5 and elements from rows 1,3,5 putting them in column 0,2,4
for (int i = 0; i < output.length; i++) {
for (int j = 0; j < output.length; j++) {
if(i==0||(i%2)==0) {
output[j][i+1]=arr[i][j];
}else {
output[j][i-1]=arr[i][j];
}
}
}
//Ignore the below code this is only used for printing the matrix
System.out.println("Input Array");
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
System.out.print(arr[i][j]+"\t");
}
System.out.println();
}
System.out.println("\n\nOuput Array");
for (int i = 0; i < output.length; i++) {
for (int j = 0; j < output.length; j++) {
System.out.print(output[i][j]+"\t");
}
System.out.println();
}
}
}
How to get Cell index after comparing values, for example i have this
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
if (dataGridView1.Rows[i].Cells[value].Value.ToString() == radTextBox1.Text)
{
//If the value matches how to get the row index of that
}
}
This might do the job:
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
if (dataGridView1.Rows[i].Cells[0].Value.ToString() == radTextBox1.Text)
{
dataGridView1.CurrentCell = dataGridView1.Rows[i].Cells[0];
}
}
If you are wanting to find the value in any cell then you need to use a nested loop.
dataGridView1.ClearSelection();
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
for (int c = 0; c < dataGridView1.Columns.Count; c++)
{
if (dataGridView1.Rows[i].Cells[c].Value.ToString() == radtextBox1.Text)
{
dataGridView1.Rows[i].Selected = true;
}
}
}
This will move through each row while checking all the columns for a value and will hilight any row where a cell has that value. Note that this code is case sensitive so "City" <> "city" but that is easily fixed using .ToUpper or .ToLower as needed.
One other thing to add, this code also is based off a DGV that has AllowUserToAddRows set to false. If you need the edit row, you either need to -1 from the count in the rows loops or check to ensure that the current row is false for .IsNewRow.
You found the Row you're looking for.
It's i variable in your code.
var requiredRowIndex = -1;
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
if (dataGridView1.Rows[i].Cells[value].Value.ToString() == radTextBox1.Text)
{
requiredRowIndex = i;
break;
}
}
if (requiredRowIndex != -1)
{
// It was found.
}
else
{
// It was not found.
}
You dont show us what is the value? It's actualy index of Cell you're looking for.
I have written the following code but it looks to be far from efficient.
//Find largest in tempRankingData
int largestIntempRankingData = tempRankingData[0, 0];
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
if (tempRankingData[i, j] > largestIntempRankingData)
{
largestIntempRankingData = tempRankingData[i, j];
}
}
}
//Find position of largest in tempRankingData
List<string> positionLargestIntempRankingData = new List<string>();
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
if (tempRankingData[i, j] == largestIntempRankingData)
{
positionLargestIntempRankingData.Add(i + "," + j);
}
}
}
//Find largest in each column
int largestInColumn = 0;
List<string> positionOfLargestInColumn = new List<string>();
Dictionary<int, List<string>> position = new Dictionary<int, List<string>>();
for (int i = 0; i < count; i++)
{
largestInColumn = tempRankingData[0, i];
positionOfLargestInColumn = new List<string>();
for (int j = 0; j < count; j++)
{
if (tempRankingData[j, i] > largestInColumn)
{
largestInColumn = tempRankingData[j, i];
}
}
for (int j = 0; j < count; j++)
{
if (tempRankingData[j, i] == largestInColumn)
{
positionOfLargestInColumn.Add(j + "," + i);
}
}
position.Add(i, positionOfLargestInColumn);
}
So, I wanted to check about the most efficient way to do this.
Whilst you're finding the largest in each column, you could also be finding the largest overall. You can also capture the positions as you go:
//Find largest in each column
int largestInColumn = 0;
int largestOverall = int.MinValue;
List<string> positionOfLargestInColumn;
Dictionary<int, List<string>> position = new Dictionary<int, List<string>>();
List<string> positionLargestIntempRankingData = new List<string>();
for (int i = 0; i < count; i++)
{
largestInColumn = tempRankingData[0, i];
positionOfLargestInColumn = new List<string>();
positionOfLargestInColumn.Add("0," + i);
for (int j = 1; j < count; j++)
{
if (tempRankingData[j, i] > largestInColumn)
{
largestInColumn = tempRankingData[j, i];
positionOfLargestInColumn.Clear();
positionOfLargestInColumn.Add(j + "," + i);
}
else if(tempTankingData[j,i] == largestInColumn)
{
positionOfLargestInColumn.Add(j + "," + i);
}
}
position.Add(i, positionOfLargestInColumn);
if(largestInColumn > largestOverall)
{
positionLargestIntempRankingData.Clear();
positionLargestIntempRankingData.AddRange(positionOfLargestInColumn);
largestOverall = largestInColumn;
}
else if(largestInColumn == largestOverall)
{
positionLargestIntempRankingData.AddRange(positionOfLargestInColumn);
}
}
1). You can find largest element and its position in one method and retrieve.
Would be caller of your method concerned about position or actual value, is a matter of concrete case.
2) You can use `yield return' technique in your matrix search (for column based search), so do not compute all column's maximas and push them into the dictionary. Dictionaries are not that fast as arrays, if you can avoid use them, do that.
3) You can keep a matrix in single dimension, long array. Have [] access operator overload, to "emulate" matrix access. Why ? If finding maximum is something frequent you might need to do during program run, having one foreach loop is faster then having 2 nested once. In case of a big matrices, single array search can be easily parallelized among different cores.
If big matrices and/or frequent calls are not your concern, just simplify your code like in points (1), (2).
For your fist two itterations you could replace with this:
//Find largest in tempRankingData
int largestIntempRankingData = tempRankingData[0, 0];
List<KeyValuePair<double,string>> list = new List<KeyValuePair<double,string>>();
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
if (tempRankingData[i, j] > largestIntempRankingData)
{
largestIntempRankingData = tempRankingData[i, j];
list.Add(new KeyValuePair<double, string>(largestIntempRankingData, i + "," + j)); //Add the value and the position;
}
}
}
//This gives a list of strings in which hold the position of largestInItemRankingData example "3,3"
//Only positions where the key is equal to the largestIntempRankingData;
list.Where(w => w.Key == largestIntempRankingData).ToList().Select(s => s.Value).ToList();
You can get all these pieces of information in a single scan with a little fiddling around. Something like this (converting the rows and columns to a string is trivial and better done at the end anyway):
int? largestSoFar = null; // you could populate this with myMatrix[0,0]
// but it would fail if the matrix is empty
int largestCol = 0;
int largestRow = 0;
int?[] largestPerColumn = new int?[numOfCols]; // You could also populate this with
// the values from the first row but
// it would fail if there are no rows
int[] largestColumnRow = new int[numOfCols];
for (int i = 0; i < numOfRows; i++)
{
for (int j = 0; j < numOfCols; i++)
{
if (largestSoFar < myMatrix[i,j])
{
largestSoFar = myMatrix[i,j];
largestCol = j;
largestRow = i;
}
if (largestPerColumn[j] < myMatrix[i,j])
{
largestPerColumn[j] = myMatix[i,j];
largestColumnRow[j] = i;
}
}
}
// largestSoFar is the biggest value in the whole matrix
// largestCol and largestRow is the column and row of the largest value in the matrix
// largestPerColumn[j] is the largest value in the jth column
// largestColumnRow[j] is the row of the largest value of the jth column
If you do need to capture all the "maxima" (for want of a better word, because that's not really what you are doing) in a column, you could just change the above code to something like this:
int? largestSoFar = null; // you could populate this with myMatrix[0,0]
// but it would fail if the matrix is empty
int largestCol = 0;
int largestRow = 0;
int?[] largestPerColumn = new int?[numOfCols]; // You could also populate this with
// the values from the first row but
// it would fail if there are no rows
List<int>[] largestColumnRow = new List<int>[numOfCols];
for (int i = 0; i < numOfRows; i++)
{
for (int j = 0; j < numOfCols; i++)
{
if (largestSoFar < myMatrix[i,j])
{
largestSoFar = myMatrix[i,j];
largestCol = j;
largestRow = i;
}
if (largestPerColumn[j] < myMatrix[i,j])
{
largestPerColumn[j] = myMatix[i,j];
largestColumnRow[j].Add(i);
}
}
}
// Now largestColumnRow[j] gives you a list of all the places where you found a larger
// value for the jth column
I am reading a csv file which has column names in first line and values in line >1. I need to get the position of the column name. The only way I can think of is to do either switch or ifs. I read it somewhere that in my case , it is faster (better) to do the ifs. However the file has many columns (~120). Just wondering if there is an alternative(s).
private static void Get_Position(string line, performance p)
{
string[] line_split = line.Split(',');
for (int i = 0; i < line_split.Length; i++)
{
if (line_split[i].Contains(#"(0)\% Processor Time"))
{
p.percore[0] = i;
}
else if (line_split[i].Contains(#"(1)\% Processor Time"))
{
p.percore[1] = i;
}
else if (line_split[i].Contains("Private Bytes"))
{}
else if (line_split[i].contains("DPC")
{
}
//on and on and on with else ifs
What is preventing you from using a loop?
for (int i = 0; i < line_split.Length; i++)
{
for(var j = 0; j < 120; j++)
{
if(line_split[i].Contains(#"(" + j + ")\% Processor Time"))
{
p.percore[j] = i;
}
}
...
To maintain the same functionality as if else if then you could use a break inside the conditional.
Edit: The edit now made it clear that there is no clear pattern to the string in contains. Still, if you are writing out 120 if/else if statements you should store what you will be looking for in some type of collection. For example, a List would work. Then access the index j of the collection in your loop:
...
var listOfSearchItems = new List<string>() { "Private Bytes", "DPC" };
for (int i = 0; i < line_split.Length; i++)
{
for(var j = 0; j < 120; j++)
{
if(line_split[i].Contains(listOfSearchItems[j])
{
p.percore[j] = i;
}
}
...
If I use break like the code below, then the loop within row won't iterate the rest if there is a match in the beginning, but what about the col loop?
Would it still iterate between 0 and 7? Is there a way to use break there as well?
for (int col = 0; col < 8; col ++)
for (int row = 0; row < 8; row ++)
if (check something)
{
//Then do this;
break;
}
One option is to use a condition flag. You could then either break in the outer loop as well, or just use it as an extra condition within the for loops:
bool keepGoing = true;
for (int col = 0; col < 8 && keepGoing; col++)
{
for (int row = 0; row < 8 && keepGoing; row++)
{
if (something)
{
// Do whatever
keepGoing = false;
}
}
}
In Java, you can specify a label to break to though. (I didn't see that this question was tagged Java as well as C#.)
outerLoop:
for (...)
{
for (...)
{
if (...)
{
break outerLoop;
}
}
}
EDIT: As noted in comments, in C#, you could use a label and goto:
for (...)
{
for (...)
{
if (...)
{
goto endOfLoop;
}
}
}
endOfLoop:
// Other code
I'd really recommend that you don't take either of these approaches though.
In both languages, it would usually be best to simply turn both loops into a single method - then you can just return from the method:
public void doSomethingToFirstOccurrence()
{
for (...)
{
for (...)
{
if (...)
{
return;
}
}
}
}
Yes, it is possible by using a break label:
package others;
public class A {
public static void main(String[] args) {
outer: for(int col = 0; col < 8; col ++)
{
for (int row = 0; row < 8; row ++)
{
if (col == 4)
{
System.out.println("hi");
break outer;
}
}
}
}
}
You can put logic like this:
boolean condition = false;
for (int col = 0; col < 8; col ++)
for (int row = 0; row < 8; row ++)
if (check something) {
// Then do this:
condition = true; // Break condition for outer loop
break;
}
}
if (condition)
break;
}
break only breaks the loop that is directly around it. You could use a flag to control the outer loop:
boolean continueOuterLoop = true;
for(int col = 0; continueOuterLoop && col < 8; col ++) {
for(int row = 0; row < 8; row ++) {
if(check something) {
//Then do this;
continueOuterLoop = false;
break;
}
}
}
It doesn't exit the col loop.
Instead, you can wrap all in a function and use return; to exit immediately from the loop
private Xy Loop( /* Parameters */)
for (int col = 0; col < 8; col ++)
for (int row = 0; row < 8; row ++)
if (check something) {
// Then do this;
return something; //Or just return;
}
}
}
}
nameHere:
for (yourForLoop) {
for (anotherLoop) {
if(condition) {
break nameHere;
}
}
}
One more alternative to the other answers is to set your counters to the maximum, to stop the loops.
for (int col = 0; col < 8; col ++)
for (int row = 0; row < 8; row ++)
if (check something)
{
// Use the col and row here.
// Now we go for a totally break of all loops.
// To stop the loops you can set that to the maximum
// of your loop test.
row = 8;
col = 8;
}
The advantage to that trick is that you do not add any additional checking code to the full loop and that makes it a lot faster.
In Java, you can use a break label.
outer:
for (int col = 0; col < 8; col ++)
for (int row = 0; row < 8; row ++)
if (check something)
{
break outer;
}
}
}
And, since nobody else has mentioned it yet, in C#, you can use goto label.
for (int col = 0; col < 8; col ++)
for (int row = 0; row < 8; row ++)
if (check something)
{
goto outside;
}
}
}
outside:
I think you should use a tag or a label, like "outerLoop". This works in Java:
outerLoop:
for (int col = 0; col < 8; col ++)
for (int row = 0; row < 8; row ++)
if (check something)
{
//Then do this;
break outerLoop;
}
There are a few ways to do this. One way is to set the max value of the variable in the outer loop.
int maxcol = 8;
for (int col = 0; col < maxcol; col++)
{
for (int row = 0; row < 8; row++)
{
if (check something)
{
Then do this;
// cause the outer loop to break:
col = maxcol;
// break the inner loop
break;
}
}
}
Set the col = 8 and then break to inner loop.
Loop1:
for (int col = 0; col < 8; col ++)
{
for (int row = 0; row < 8; row ++)
{
if (condition)
{
break Loop1;
}
}
}
This could do what you need.
We could use the concept of a flag variable:
flag = 1;
for (int col = 0; col < 8; col ++)
{
if (flag == 1)
{
for (int row = 0; row < 8; row ++)
{
if (flag == 1)
{
if (check something)
{
//Then do this;
flag = 0;
}
}
}
}
}