I have a foreach loop like this where I want the else condition to output: "unit not found" if the quad.ID == searchForQuadcopters isn't found but I get this string value output even when the value is found.
foreach (var quad in allQuadcopters)
{
if (quad.ID == searchForQuadcopter)
{
WriteLine("Value found.");
// write here all the information you want to display.
WriteLine($"ID: {quad.ID}");
WriteLine($"Capacity (kg): {quad.capacityKg}");
WriteLine($"Reach (km): {quad.reachKm}");
WriteLine($"Transponder ID: {quad.transponderID}");
quad.vehicleDeliveryForm();
}
else
{
WriteLine("Unit not found");
}
}
You won't know if the value isn't found unless you iterate over the ENTIRE list first and don't encounter it.
Create a boolean flag to track whether the value was found or not:
bool found = false;
foreach (var quad in allQuadcopters)
{
if (quad.ID == searchForQuadcopter)
{
found = true;
WriteLine("Value found.");
// write here all the information you want to display.
WriteLine($"ID: {quad.ID}");
WriteLine($"Capacity (kg): {quad.capacityKg}");
WriteLine($"Reach (km): {quad.reachKm}");
WriteLine($"Transponder ID: {quad.transponderID}");
quad.vehicleDeliveryForm();
break; // if you don't want to iterate over the rest
}
}
if (!found) {
WriteLine("Unit not found");
}
I want the else condition to output: "unit not found" if the quad.ID == searchForQuadcopters isn't found
Then you don't want this loop. Your code loops over all items, and if allQuadcopters contains Ids 1, 2 and 3 and you're looking for 2, it will print "Unit not found" for Ids 1 and 3. You could break; out of the loop in your if(), but then the else will still be hit for 1.
You want to leverage Linq here:
var quad = allQuadcopters.FirstOrDefault(q => q.ID == searchForQuadcopters);
if (quad == null)
{
WriteLine("Unit not found");
}
else
{
WriteLine("Value found.");
// write here all the information you want to display.
WriteLine($"ID: {quad.ID}");
}
Related
I have two lists of objects: List<One> & List<Two> and I want to achieve the following.
For each One.Id:
if there's a matching Id in Two.Id, do nothing
else if there are no matching Ids in Two.Id, do something
I tried with iteration inside iteration, but couldn't find a suitable solution.
Thanks in advance.
You can use LINQ's Any() method to check for presence of matching items:
foreach (var one in listOne) {
if (!listTwo.Any(two => two.Id == one.Id)) {
// No matches
}
}
I would use Any() in a dedicated function like this:
bool HasMatches(List<One> ones, List<Two> twos)
{
foreach (var item in ones) {
if (!twos.Any(other => other.Id == item.Id))
return false;
}
return true;
}
You should finish the search once you have found no match for the current item.
foreach(var item1 in list1)
{
if(list2.Any(item2=>item2.Id== item1.Id))
{
//do nothing
continue;
}
// do something
}
you can do some thing like this
List<one> a = new List<one>;
List<two> b = new List<two>;
foreach( l in a)
{
if(b.Any(x=>x.id == l.id)){
//do something
}
else{
//do something
}
}
You can use Contains like this.
bool isContainId = List<one>.Contains(two.Id);
if (isContainsId)
{
// do something
}
else
{
// do something
}
So I am trying to loop though items that are in a listbox in my application. The list box will allow you to select multiple items to which I have a method tied to each item in the listbox. I have a counter variable incremented each time the loop works.When I use the foreach loop with the switch statement below, it does the first item correct, but then loops through the same item again. I know I am missing something as it is supposed to go to the next item in the listbox and not the same item.
string reportname = lstbxReports.SelectedValue.ToString();
int i = 0;
foreach (var report in reportname)
{
switch (reportname)
{
case "Overview":
{
if (i < 1)
{
PrintOverview(filename);
}
else if (i >= 1)
{
PrintOverviewAppend(filename);
}
break;
}
case "Sources":
{
if (i < 1)
{
PrintSource(filename);
}
else if (i >= 1)
{
PrintSourceAppend(filename);
}
break;
}
}
i++
Any thoughts or suggestions on how I can get the foreach loop to go to the next item in the selected listbox?
Also, this is just a snippet as I have about 11 case items to loop through.
You probably want to switch on report, not reportname.
foreach(string item in listBox.Items)
{
}
?
Depends on how you setup the data source for the listbox though (I'm assuming this is WinForm?). If you created it by adding .Items or using the designer then this will work. However if you've used .DataSource then it wont work.
I'd personally have a
List<string> list = SomeMethodWhereIMakeTheList();
and set that to:
listbox.DataSource = list;
then I wouldn't even have to touch the ListBox to mess with the contents:
list.ForEach(...)
Don't do the print logic in a foreach. Split out the data then print such this (note I changed the name of reportname to reportnames to signify a list of items)
string reportnames = lstbxReports.SelectedValue.ToString();
var firstReport = reportnames.First(); // No error checking here, would use FirstOrDefault with null checks.
if (firstReport == "OverView")
PrintOverview(filename);
else
PrintSource(filename);
// Now print out the rest
reportnames.Skip(1)
.ToList()
.ForEach(rp =>
{
if (rp == "OverView")
PrintOverviewAppend(filename);
else
PrintSourceAppend(filename);
});
I am trying to check that an item doesn't already exist in a list box before I add the new item.
if (TeamNameTextBox.Text != "")
{
if (TeamNameListBox.Items.FindByValue(TeamNameListBox.Text) == null)
{
TeamNameListBox.Items.Add(TeamNameTextBox.Text);
TeamNameTextBox.Text = "";
int teamCountUpdate = TeamNameListBox.Items.Count;
if (teamCountUpdate == 1)
{
TeamCount.Text = teamCountUpdate.ToString() + " Team";
}
else
{
TeamCount.Text = teamCountUpdate.ToString() + " Teams";
}
}
else
{
AddTeamSeasonError.Text = "This team has already been added";
}
}
else
{
AddTeamSeasonError.Text = "Please select a team";
}
I have got it to check if the text box is blank, but I need to check that the item a user is trying to add is not already in the the list box.
I have tried the line:
if (TeamNameListBox.Items.FindByValue(TeamNameListBox.Text) == null)
But that doesn't work, any suggestions on how I can do the check?
Use this:
if (!TeamNameListBox.Items.Contains(TeamNameTextBox.Text))
TeamNameListBox.Items.Add(TeamNameTextBox.Text);
think you should at least try to use TeamNameTextBox instead of TeamNameListBox as argument
if (TeamNameListBox.Items.FindByValue(TeamNameTextBox.Text) == null)
I suppose you mean
// search if the textbox value is found in the list. this comment shouldn't be part of the code
if (TeamNameListBox.Items.FindByValue(TeamNameTextBox.Text) == null)
instead of
if (TeamNameListBox.Items.FindByValue(TeamNameListBox.Text) == null) // code from question
EDIT: There is no need to put the name of the type of the control next to the variable.
i.e. instead of TeamNameListBox, use teamNames. And, instead of TeamNameTextBox, use teamName.
Okay, well let's say I have a variable list of items. It can be any number of items. Each item can be either 0,1,2,3, or 4. So I make a loop.
foreach(item in allitems)
{
if (item == 0) continue;
do stuff for items 1-4.
}
Let's say that every single item it goes through is 0. Well what if I want to execute a specific line of code in that case? Of course I could do something like
int count = 0
foreach(item in allitems)
{
if (item == 0) {count++; continue;}
do stuff for items 1-4.
}
if(count == allitems.Count())
{
do stuff
}
But I always felt cheap using count variables to do something like this. Is there any thing I can do that doesn't feel like duct-taping a solution together?
There's no need to use a count here - just keep a flag which is set if you get past the check, rather than within the check:
bool anyNonZeroItems = false;
foreach(item in allitems)
{
if (item == 0)
{
continue;
}
anyNonZeroItems = true;
// Whatever else
}
if (!anyNonZeroItems)
{
// Everything was 0 (or the collection was empty)
}
You can use Enumerable.All to check if all items in a List satisfy a condition.
in this case something like
if (allItems.All(i => i == 0) {
//do stuff
}
Incidentally in your example you have (if item = 0) and this should be if (item == 0)
What you currently have is perfectly acceptable. I use that kind of pattern all the time.
One thing I would suggest is making count into a bool unless there's an actually a difference between when count == 11 andcount > 1`
This is a pretty common problem, but you propose an odd solution. Why not just use a boolean to indicate state?
bool branchExecuted = false;
foreach(item in allitems)
{
if (item == 0)
{
branchExecuted = true;
continue;
}
//do stuff for items 1-4.
}
if(!branchExecuted)
{
//do stuff if we never hit that line
}
Using this instead of a LINQ / convenience function to operate on the list will only cost you a single boolean and you only have to iterate over your list once.
this.entityModel.Entities is a source to my datagrid(agdatagrid).
I have kept AutoGenerateColumns="False".
i have 6 columns in my agdatgrid
i want 6th column to be visible depending on the data of that column..ie., if any row of that column contains the data then it should be visible and if none of the row contains the data for that column it should be invisible.
So i have written a foreach loop but it takes more time to get ui loaded if the data is large. so is there any other way ?
foreach (BrowserEntity _browseEntity in this.entityModel.Entities)
{
if (_browseEntity.State != null && this.entityModel.Entities.Count>0)
{
this.grid.DataSource = this.entityModel.Entities;
this.grid.Columns[6].Visible = true;
break;
}
else
{
this.grid.DataSource = this.entityModel.Entities;
this.grid.Columns[6].Visible = false;
}
}
First look at the logic of what you're writing. You're checking whether the count of a collection is greater than zero inside a loop that iterates over it; this will always return true as the loop will not run if the collection contains anything. So what you're actually writing is this, when code that either always returns true or which cannot execute is removed:
foreach (BrowserEntity _browseEntity in this.entityModel.Entities)
{
if (_browseEntity.State != null)
{
this.grid.DataSource = this.entityModel.Entities;
this.grid.Columns[6].Visible = true;
break;
}
}
So you're assigning the data source a number of times, and never setting Visible to false, whereas I think what you're actually trying to write is something like this:
// bind the grid but hide column 6
this.grid.DataSource = this.entityModel.Entities;
this.grid.Columns[6].Visible = false;
// if there is any state then show column 6
foreach (BrowserEntity _browseEntity in this.entityModel.Entities)
{
if (_browseEntity.State != null)
{
this.grid.Columns[6].Visible = true;
break;
}
}
Alternatively, using Linq, this could be written as the following, which achieves the same thing but is much clearer:
this.grid.DataSource = this.entityModel.Entities;
this.grid.Columns[6].Visible = this.entityModel.Entities.Any(e => e.State != null);
I'm not an expert on this...but why are you resetting the DataSource every time?
bool isColumnVisible = false;
this.grid.DataSource = this.entityModel.Entities;
foreach (BrowserEntity _browseEntity in this.entityModel.Entities)
{
if (_browseEntity.State != null && this.entityModel.Entities.Count>0)
{
isColumnVisible = true;
break;
}
}
this.grid.Columns[6].Visible = isColumnVisible;
I think this should be faster...at least I hope so.
I'm not a silverlight developer, but why do you check for "this.entityModel.Entities.Count>0" in the foreach loop? I would assume the count is always >0 when you enter the loop, isn't it?