How can I iterate through an array and skip any empty items? - c#

I have taken a csv, made from an excel file, and put it into a data table. There are cells from the excel csv file that are empty and when I iterate through them, they are also iterated through. I wish to not iterate over them.
foreach (DataRow datarow in sorted.Rows)
{
Boolean first = true;
Console.Write(Environment.NewLine);
foreach (var item in datarow.ItemArray)
{
if (item != null)
{
int i = 0;
if (first)
first = false;
else
Console.Write(",");
Console.Write(item);
}
else
break;
}
}
I have tried the above and it still iterates through the empty cells.

Expanding on JohnD answer, you can try this, assuming you only want to output the fields to the Console:
var text = string.Empty;
foreach (DataRow datarow in sorted.Rows)
{
var items = datarow.ItemArray
.Where(x => ((x != null) && !string.IsNullOrEmpty(x.ToString())));
var textJoined = string.Join(",", items);
text += textJoined + Environment.NewLine;
}
Console.WriteLine(text);
You may not be familiar with LINQ, so you will need the following using statement:
using System.Linq;
Again this solution assumes you only want to output the values to the console window, it does not assume you want to iterate through all the columns for a given row. If that is what you want let me know and I can make the appropriate modifications
[edit]
whoops just re-read your question and it appears you do want to iterate through each column, so here is a solution below:
var text = string.Empty;
foreach (DataRow datarow in sorted.Rows)
{
var items = datarow.ItemArray
.Where(x => ((x != null) && !string.IsNullOrEmpty(x.ToString())));
var currentLine = string.Empty;
foreach(var item in items)
{
// do something with item
// in this case append to currentLine
currentLine += item + ",";
}
text += currentLine.Substring(0, currentLine.Length - 2) + Environment.NewLine;
}
Console.WriteLine(text);
You get the same result, you can now just do what you need for each item

Assuming that the item is really a string, check to see if item is null or empty using String.IsNullOrEmpty().
if (item != null && !String.IsNullOrEmpty(item.ToString()))
Additionally, replace the break statement with a continue

Why not like this?
// ItemArray is object[]
foreach (var item in datarow.ItemArray)
{
if (first)
{
first = false;
}
else
{
// I think you are expecting to see the comma here even the previous element is empty e.g. A,B,,D (that missing C)
Console.Write(",");
}
// so here we cannot guarantee "if (item is string)"
if (item != null)
{
Console.Write(item.ToString());
}
}
(My habit to wrap all codes in {})

foreach (DataRow datarow in sorted.Rows)
{
Boolean first = true;
Console.Write(Environment.NewLine);
foreach (var item in datarow.ItemArray)
{
if (!string.IsNullOrEmpty((item ?? "").ToString()))
{
int i = 0;
if (first)
first = false;
else
Console.Write(",");
Console.Write(item);
}
else
continue;
}
}

Related

foreach ending before going through all of the list

When running the code, it only goes through a small part of the rows in tableSiblings.Rows
I also tried using for instead of foreach (of course change the inside of the ()) but it still didn't work.
What can I Do?
dsSiblings = dal.GetDataSet("Select * From Siblings");
// Go through the table:
foreach (DataGridViewRow row in tableSiblings.Rows)
{
// If this is a new row:
if ((row.Cells["siblingID"].Value ?? string.Empty).ToString() == string.Empty.ToString())
{
DoSomething();
}
else
{
// Go through the database:
foreach (DataRow dr in dsSiblings.Tables[0].Rows)
{
// If a sibling with the same ID exists:
if ((row.Cells["siblingID"].Value ?? string.Empty).ToString() == dr["siblingID"].ToString())
{
DoSomethingElse();
break;
}
}
}
}
dal.UpdateDataSet(dsSiblings);

How can I copy a rows' values into new row datagridview c#

I have a datagridview with 5 columns.
For each new rowadded I want to copy the last rows' values into the new one except for one.
can anyone help me pls?
I'm a bit new to c# :/
I've been trying something like this
foreach (DataGridViewColumn Column in dataGridView1.Columns)
{
foreach (DataGridViewCell cell in dataGridView1.Rows)
{
if (cell.RowIndex != lastrowindex)
{
if (cell.FormattedValue == String.Empty)
{
listNames.Add(cell.Value.ToString());
}
}
}
}
string strNames = null;
foreach (string name in listNames)
strNames += name + Environment.NewLine;
MessageBox.Show("List of all rows\n\n" + strNames);
Is this correct?
if (cell.FormattedValue == String.Empty)
{
listNames.Add(cell.Value.ToString());
}
I can imagine that if FormattedValue is empty, than cell.Value.ToString() is also empty. If so... your collection listNames is filled with empty strings result in strNames which exists only of newlines...
Perhaps you want to change == into !=:
if (cell.FormattedValue != String.Empty)
{
listNames.Add(cell.Value.ToString());
}

Replace foreach with linq

dt = ds.Tables[1];
foreach (EPSFromElement element in elementList)
{
foreach (DataRow row in dt.Rows)
{
foreach (DataColumn column in dt.Columns)
{
var ColumnName = column.ColumnName;
var ColumnData = row[column].ToString();
var currentElement = Regex.Replace(element.Field_Label, #"\W", "");
if (element.Module_Field_ID != null)
{
if (currentElement == ColumnName)
element.ColumnValue = ColumnData;
}
else
{
if (element.Field_Type_Name != "Checkbox")
{
if ("Q_" + element.Column_Name_ID == ColumnName)
element.ColumnValue = ColumnData;
}
else
{
if ("Q_" + element.Column_Name_ID + "_" + element.Value_Column_Name_ID == ColumnName)
element.ColumnValue = ColumnData;
}
}
}
}
}
I have a List of object(EPSElement). In EPSElement there is a field ColumnValue that gets data from a data table (dt = ds.Tables[1];). To achieve this i am using there foreach loop .Is there a better way to do this. I am not too happy with three for each loop. Can this be replaced by LINQ.
I would never attempt to replace that with LINQ. First, you're mutating inside the body of the foreach and that's a bad idea to attempt to do with LINQ. LINQ is about querying (the 'Q' in LIN Q is for q uery) and so shouldn't have side effects. But, even supposing that you were to replace the mutation with a projection to a new sequence of objects, converting that to LINQ would be very hard to read; too much nested logic. Leave it alone.
This translates reasonably well. Each of the foreach-es translate into their own from, the few variables are each lets, and all of the ifs end up being where's.
var query = from element in elementList
from row in dt.Rows.Cast<DataRow>()
from column in dt.Columns.Cast<DataColumn>()
let ColumnName = column.ColumnName
let ColumnData = row[column].ToString()
let currentElement = Regex.Replace(element.Field_Label, #"\W", "")
where (element.Module_Field_ID != null && currentElement == ColumnName)
|| (element.Field_Type_Name != "Checkbox"
&& "Q_" + element.Column_Name_ID == ColumnName
|| element.Field_Type_Name == "Checkbox"
&& "Q_" + element.Column_Name_ID + "_" + element.Value_Column_Name_ID == ColumnName)
select new { Element = element, ColumnData = ColumnData };
foreach (var item in query)
item.Element.ColumnValue = item.ColumnData;
Note that since the logic in the Where is a bit complex, it may be best to refactor it out into it's own method in which you have something like:
where IsValid(element, ColumnName, currentElement)
The implementation can then be the logic in either my query or your original code, based on which you'd prefer.

loop through checkedListBox items without the select all item

I want to get the items from a checkedListBox into a List<>, but without the select all/ deselect all (first checkbox)..can't figure it out how to not add the first item..
this is the code:
foreach (string s in checkedListBoxDepts.CheckedItems)
{
if (checkedListBoxDepts.SelectedItems.IndexOf(s) == 0)
continue;
list.Add(s);
}
then I take the items and put in another list to avoid errors:
foreach (string s in list)
{
list2.Add(s);
}
but still the select all is loaded...help
Try:
foreach (var s in checkedListBoxDepts.CheckedItems)
{
if (checkedListBoxDepts.IndexOf(s) == 0)
continue;
list.Add(s.ToString());
}
foreach (string s in checkedListBoxDepts.CheckedItems)
{
if (checkedListBoxDepts.SelectedItems.IndexOf(s) == 0)
continue;
list.Add(s);
}
after that remove first item from list
list.removeat(0);

Write Values from Checkbox to Text File and Count the Minimum and Maximum Selected Values

After I do this it's not doing anything that I want to do or otherwise, it writes twice to the file in one line.
The code bellow try to write a value from check box into a text file then find the maximum and minimum value.
List<string> myLs = new List<string>();
int checke = 0;
foreach (ListItem item in coursess.Items)
{
if (item.Selected)
{
checke = checke + 1;
}
}
if (checke < 4)
{
kk.Text = "less";
kk.Visible = true;
}
else if (checke > 6)
{
kk.Text = "More";
kk.Visible = true;
}
else if(checke == 4 || checke == 5 || checke == 6)
{
foreach (ListItem item in coursess.Items)
{
if (item.Selected)
{
myLs.Add(item.Value);
}
}
String datas = String.Join(",", myLs.ToArray());
Based on your code, it looks like a message will be displayed when less than four or more than six checkboxes are checked. As for writing the string to a file, how about something like this at the end...
System.IO.File.WriteAllText(#"C:\selectedcourses.txt", datas);
This should write the entire string, once, to the path that you choose.

Categories