baltermia
baltermia

Reputation: 1343

Is it possible to `continue` a foreach loop while in a for loop?

Okay, so what I want to do should sound pretty simple. I have a method that checks every character in a string if it's a letter from a to m. I now have to continue a foreach loop, while in a for loop. Is there a possible way to do what I want to do?

public static string Function(String s)
{
    int error = 0;
    foreach (char c in s)
    {
        for (int i = 97; i <= 109; i++)
        {
            if (c == (char)i)
            {
                // Here immediately continue the upper foreach loop, not the for loop
                continue;
            }
        }
        error++;
    }

    int length = s.Length;
    return error + "/" + length;
}

If there's a character that's not in the range of a to m, there should be 1 added to error. In the end, the function should return the number of errors and the number of total characters in the string, f.E: "3/17".

Edit

What I wanted to achieve is not possible. There are workarounds, demonstrated in BsdDaemon's answer, by using a temporary variable.

The other answers fix my issue directly, by simply improving my code.

Upvotes: 0

Views: 728

Answers (5)

Barns
Barns

Reputation: 4848

Regular Expressions are perfectly suited to handle this type of "problem" and is considerably more flexible...for one thing you would not be limited to consecutive characters. The following console app demonstrates how to use Regex to extract the desired information from the targeted string.

private static string TestSearchTextRegex(string textToSearch)
{
    var pattern = "[^a-m]";
    var ms = Regex.Matches(textToSearch, pattern);

    return $"{ms.Count}/{textToSearch.Length}";
}


NOTE

The pattern "[^a-m]" basically says: find a match that is NOT (^) in the set of characters. This pattern could easily be defined as "[^a-mz]" which in addition to characters "a-m" would also consider "z" to also be a character that would not be counted in the error group.

Another advantage to the Regex solution, you are able to use the actual characters you are looking for as apposed to the number that represents that character.

Upvotes: 1

Johnathan Barclay
Johnathan Barclay

Reputation: 20354

How about using LINQ:

int errors = s
    .Count(c => !Enumerable.Range(97, 13).Contains(c));

Then there is no need to break out of the loop.

Or to avoid the nested loop altogether, which will improve performance:

int errors = s.Count(c => c < 97 || c > 109);

char is implicitly convertible to int so there's no need to cast.

Upvotes: 4

BsdDaemon
BsdDaemon

Reputation: 26

You can do this by breaking the internal loop, this means the internal loop will be escaped as if the iterations ended. After this, you can use a boolean to control with continue if the rest of the underlying logic processes:

    public static string Function(String s)
    {
        int error = 0;
        foreach (char c in s)
        {
            bool skip = false; 

            for (int i = 97; i <= 109; i++)
            {
                if ('a' == (char)i)
                {
                    skip = true;
                    break;
                }
            }

            if (skip) continue;
            error++;
        }
        string length = Convert.ToString(s.Length);
        return error + "/" + length;
    }

Upvotes: 1

Sathish Guru V
Sathish Guru V

Reputation: 1479

The continue will skip the further lines in that iterations and if you need to break out the loop use break.

public static string Function(String s)
{
    int error = 0;
    foreach (char c in s)
    {
        for (int i = 97; i <= 109; i++)
        {
            if ('a' == (char)i)
            {
                break; // break the whole looping, continue will break only the iteration
            }
        }
        error++;
    }
    string length = Convert.ToString(s.Length);
    return error + "/" + length;
}

Upvotes: -1

Patrick Beynio
Patrick Beynio

Reputation: 858

i think ('a' == (char)i) should be (c == (char)i) .
and why not replace the for with just if((int)c >= 97 && (int)c <= 109)? you solution might work but is extremly unperformant

Upvotes: 4

Related Questions