Reputation: 1343
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".
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
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
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
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
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
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