For loop - continue if boolean condition evaluates to false - c#

I am writing a for loop with multiple if statements.
Is it possible that if the if statement (or one part of it) in the for statement evaluates to false, then the loop does not exit but the integer to iterates increments by one and continues through the loop (I need functionality like the continue; keyword).
Example:
for (int i = 0; i <= Collection.Count && Collection[i].Name != "Alan"; i++)
{
// If name is not Alan, increment i and continue the loop.
}
Is this possible?
Thanks

You need functionality like the continue keyword - have you considered using the continue keyword, then?
Update: Your example code is hard to decipher the intention of.
for (int i = 0; i <= Collection.Count && Collection[i].Name != "Alan"; i++)
{
// If name is not Alan, increment i.
}
The for loop has three parts to it, separated by two semi-colons. The first part initializes the loop variable(s). The second part is an expression that is evaluated each time an iteration is about to start; if it is false, the loop terminates. The third part executes after each iteration.
So your loop above will exit at the first "Alan" it encounters, and also it will increment i every time it finishes an iteration. Finally, if there are no Alans, it will execute the last time with i equal to Collection.Count, which is one larger than the maximum valid index into the collection. So it will throw an exception for sure, as you try to access Collection[i] when i is out of range.
Maybe you want this:
foreach (var item in Collection.Where(i => i.Name != "Alan"))
{
// item is not an "Alan"
}
You can think of the Where extension method as a way of filtering a collection.
If this seems obscure, you can achieve the same thing with the continue keyword (as you guessed):
foreach (var item in Collection)
{
if (item.Name == "Alan")
continue;
// item is not an "Alan"
}
Or you can just put the code in the if's block:
foreach (var item in Collection)
{
if (item.Name != "Alan")
{
// item is not an "Alan"
}
}

Do you mean like this?
for (int i = 0; i < 100; ) {
if (!condition1) {
i++;
}
if (!condition2) {
i++;
}
if (!condition3) {
i++;
}
}
Do you want the incrementor for finishing the for loop to be in the body of the loop?

I am not sure I understand correctly. You have a for loop something like this
for (int i = 0; i < 10; i++)
{
// do something
if (!b1)
i++
// do something
}
Edit:
If you use continue it increments i for only once. If you use i++ in loop it increments twice obviously. If you only want to icrement on a condition, Use the for loop like this
for (int i = 0; i < 10) // and this is very similar to a while loop.

From your sample code, I think you are searching for the name "Alan".
Is this correct?
If so, structure your loop like:
for (int i = 0; i < Collection.Count; i++)
{
if (Collection[i].Name == "Alan")
{
break; // We found the name we wanted!
}
// Otherwise: Keep going to look for the name further on.
}
if (i == Collection.Count)
{
Console.WriteLine("Alan is not found");
}
else
{
Console.WriteLine("Alan found at position {0}", i);
}

Related

Temporary Index for a while loop

I have a loop with an index. But the index jumps up and down from time to time, so a for loop is out of the question. But I still need the index. I just don't like the idea of having a temporary index in my function which I am only using for one loop. e.g.
...
int i = 0;
while( i < something)
{
if(a)
i++:
else
i--:
}
...
Can I make i temporary for the loop? Maybe something like this?
...
temporary (int i = 0)
{
while( i < something)
{
if(a)
i++:
else
i--:
}
}
...
You can use the for loop in order to achieve this. the variable i will live only inside the for loop scope.
for (int i = 0; i < something;;)
{
if(a)
i++:
else
i--:
}
}
You can limit the range of a variable by enclosing its declaration and its use within curly braces. It looks a litte bit strange, but it works fine.
Then your i variable can't be accessed outside of this scope as shown below (you will get a compilation error) :
MyMethod()
{
// ... lots of code here
{
int i=0;
while( i < something)
{
if(a)
i++;
else
i--;
}
i--; // ok
}
i--; // error : The name 'i' does not exist in the current context
// ... some more code here
}

Checking every array member in an if statement to look for a specific array member

I'm trying to create a system where I have a string array where each member says the same thing ("Empty") but an if statement/foreach combo changes just one of those "Empty"s to a "Full" when a button is clicked. So first I start the if statement with something like
if (inv[0] == "Empty" || inv[1] == "Empty" || inv[2] == "Empty")
etc till it covers each member of the array making sure that there is at least one "Empty" (for it's supposed to only change an "Empty" to "Full" if there actually is an "Empty").
After that, I think I'm supposed to use a foreach, but I'm not sure how.
Anyway, any help would be appreciated. If you need me to send me my code, let me know.
You can find if any of item is empty like this.
bool isEmptyFound = false;
foreach (var item in inv)
if (item.Equals("Empty", StringComparison.OrdinalIgnoreCase))
{
isEmptyFound = true;
break;
}
//if isEmptyFound == true there is atleast one item that is "Empty"
You can not change item value by foreach you need to use simple for loop.
for (int i = 0; i < inv.Length; i++)
if (inv[i].Equals("Empty", StringComparison.OrdinalIgnoreCase))
{
inv[i] = "Full";
break;
}
Why not just use Array.IndexOf to find the index of a Empty and then change it to Full, like so:
int indexOfEmpty = Array.IndexOf(inv, "Empty");
//check if inv has a value set to "Empty"
if (indexOfEmpty != -1)
{
//change the "Empty" we found at indexOfEmpty to "Full"
inv[indexOfEmpty] = "Full";
}
If you are looking to do it manually with a loop, then you can just use a for loop like so:
bool foundEmpty = false;
for (int i = 0; i < inv.Length; i++)
{
if (inv[i] == "Empty")
{
inv[i] = "Full";
foundEmpty = true;
break;
}
}

How to repeat one loop in foreach

Hi guys how can you repeat one iteration in a foreach?
foreach (string line in File.ReadLines("file.txt"))
{
// now line == "account", next line == "account1"
if (line.Contains("a"))
//next loop take "account1";
else
// need to set that next loop will take line == "account" again
}
How to do it?
While I don't fully understand your example, I think I understand your question. I had the same problem and was able to come up with a solution: include a while loop within the foreach. In your example it would look like this:
foreach (string line in File.ReadLines("file.txt"))
{
bool repeat = true;
while (repeat)
{
// now line == "account", next line == "account1"
if (line.Contains("a"))
{
//do your logic for a break-out case
repeat = false;
}
else
{
//do your logic for a repeat case on the same foreach element
//in this instance you'll need to add an "a" to the line at some point, to avoid an infinite loop.
}
}
}
I know I'm very late to the game, but hopefully this will be helpful for anyone else who stumbles in here with the same problem.
There is no need to change your code, assuming it only has an if/else construct in the loop.
When the if condition evaluates to true the else will not execute and the loop resumes.
In a more complex where you want to immediately resume the loop and ensure nothing else following the condition executes, use the continue statement:
The continue statement passes control to the next iteration of the enclosing while, do, for, or foreach statement in which it appears.
foreach (string line in File.ReadLines("file.txt"))
{
// now line == "account", next line == "account1"
if (line.Contains("a"))
continue;
else
// need to set that next loop will take line == "account" again
// more stuff that we don't want to execute if line.Contains("a")
}
I guess this might also helpful if someone else come
for (int i = 0; i < inventoryTimeBlocks.Count; i++)
{
if (line.Contains("a"))
//next loop take "account1";
else
{
if(i > 0)
{
i = i - 1;
continue;
}
}
}

Equivalent of Ruby "redo" in C#

Is there an equivalent method of performing the job of redo in C#? i.e. going back to the top of the loop and re-execute without checking conditions or increasing the loop counter. Thanks.
for (int i = 0; i < 100; i++)
{
do
{
DoYourStuff();
} while (ShouldWeDoThatAgain());
}
Do...while is like a standard while loop, except instead of checking its conditional before each iteration, it checks after. That way, the code inside the loop will always execute at least once. Stick that inside a for or foreach loop, and that should get you the behavior your want. This is a bit simpler than Simon's answer, as it doesn't require an extra variable, doesn't use continue, and doesn't mess with the loop counter at all.
Why not simply:
Although goto is not really everyone's favourite, it's quite readable in this case...
for(...)
{
redo:
//...
if (...)
goto redo;
}
No. The closest you'll get is something like this:
bool redoCalled = false:
for (int i = 0; i < 10; i++) {
if (redoCalled) {
i--;
redoCalled = false;
}
// other stuff here
if (redoWanted) {
redoCalled = true;
continue;
}
}

CLR is optimising my forloop variables away

I'm trying to run a basic loop that will find a specific value in a dataview grid. I cannot figure out whats going on with the code, since the for loop exits before evaluating its basic condition.
private void SearchDataViewGrid(string FileName)
{
//finds the selected entry in the DVG based on the image
for (int i = 0; i == dataPartsList.Rows.Count ; i++)
{
if(FileName == dataPartsList.Rows[i].Cells[3].Value.ToString())
{
dataPartsList.Rows[i].Selected = true;
}
}
}
The program doesn't crash, but i get an error on my 'i' variables declaring that it has been optimised away. Tried a few easy fixes i found online but nothing seems to keep it.
I have verified that the string i am passing is the correct one, and my 'dummy' DVG returns a value of 14 for the number of rows contained. Even if i remove the 'if' statement inside of the for loop, i still get the same error.
The condition cond in the middle of for(init; cond; update) is not an until condition but a while condition.
So you need to change it to
for (int i = 0; i < dataPartsList.Rows.Count ; i++)
The problem is your conditional is i == dataPartsList.Rows.Count so the body will only execute when these two values are equal. This guarantees your loop will never execute. You need to change your conditional to be < instead of ==
for (int i = 0; i < dataPartsList.Rows.Count ; i++) {
...
}

Categories

Resources