2

I am trying to do is something like this:

StringBuilder sb = new StringBuilder();
foreach(char ch in valor)
{
 if (ch == ',')
 ch = '.';
 else if (ch == '0' || ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5' || ch == '6' || ch == '7' || ch == '8' || ch == '9' || ch == ',')
 {
 sb.Append(ch);
 }
}

What I want is, if the character is a comma, to make it a dot. But i get the following error

it is not possible to assign value to 'ch' because it is a foreach interaction variable

asked Jan 28, 2021 at 12:59
4
  • 1
    What is the end goal? Also ch == ',' is present both in if and else if which does not make much sense. Commented Jan 28, 2021 at 13:03
  • 1
    Possible duplicate. Commented Jan 28, 2021 at 13:07
  • The lang spec explicitly states "The variable v is read-only in the embedded statement." but not why. learn.microsoft.com/en-us/dotnet/csharp/language-reference/… Commented Jan 28, 2021 at 13:12
  • alternative approaches if ("0123456789.".Contains(ch)) or if (char.IsDigit(ch) || ch == '.') Commented Jan 28, 2021 at 13:27

4 Answers 4

3

Why not append in both if branches?

foreach(char ch in valor)
{
 if (ch == ',')
 {
 sb.Append('.');
 }
 else if (ch == '0' || ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5' || ch == '6' || ch == '7' || ch == '8' || ch == '9')
 {
 sb.Append(ch);
 }
}
answered Jan 28, 2021 at 13:06
Sign up to request clarification or add additional context in comments.

4 Comments

Or use string.Replace( ",", ".") prior to the foreach?
Oh God, don't know how I didn't think about it... Thanks!
@Fildor Yes, that's how I would do it, but the question was a little different. There are probably 100 million ways to do it.
Absolutely. It's just the first thing that came to my mind... Also, to me the question seems a little like "how can I do x, while I am not allowed to do x" ... so hard to answer, anyway.
0

Short answer: it is impossible.

Using an immutable foreach indexed item you need to use an intermediate variable like that:

foreach ( char ch in valor )
{
 char c = ch;
 if ( c == ',' )
 {
 c = '.';
 }
 if ( c == '0' || c == '1' || c == '2' || c == '3' || c == '4'
 || c == '5' || c == '6' || c == '7' || c == '8' || c == '9'
 || c == '.' )
 {
 sb.Append(c);
 }
}

I removed the else because it seems to be a mistake...

But in this case you may prefer directly use a for to avoid this useless intermediate variable and so to optimize speed and memory:

for (int index = 0; index < valor.Length; index++)
{
 char c = valor[index];
 if ( c == ',' )
 {
 c = '.';
 }
 if ( c == '0' || c == '1' || c == '2' || c == '3' || c == '4'
 || c == '5' || c == '6' || c == '7' || c == '8' || c == '9'
 || c == '.' )
 {
 sb.Append(c);
 }
}

Next, in the case of the code provided, we can refactor like that, using the else in the right way now:

for (int index = 0; index < valor.Length; index++)
{
 char c = valor[index];
 if ( c == ',' )
 {
 sb.Append('.');
 }
 else
 if ( c == '0' || c == '1' || c == '2' || c == '3' || c == '4'
 || c == '5' || c == '6' || c == '7' || c == '8' || c == '9' )
 {
 sb.Append(c);
 }
}

Also, in the case of the code provided, we can improve to this:

for ( int index = 0; index < valor.Length; index++ )
{
 char c = valor[index];
 if ( c == ',' )
 {
 sb.Append('.');
 }
 else
 if ( char.IsDigit(c) ) // or IsNumber
 {
 sb.Append(c);
 }
}

And to optimize better:

for ( int index = 0; index < valor.Length; index++ )
{
 char c = valor[index];
 if ( c == ',' )
 {
 sb.Append('.');
 }
 else
 if ( c >= '0' && c <= '9' )
 {
 sb.Append(c);
 }
}

So using a foreach we can write, but a little less optimized while being more clean:

foreach (char ch in valor )
{
 if ( ch == ',' )
 {
 sb.Append('.');
 }
 else
 if ( ch >= '0' && ch <= '9' )
 {
 sb.Append(ch);
 }
}

Char.IsDigit Method

Char.IsNumber Method

foreach, in (C# reference)

for (C# reference)

answered Jan 28, 2021 at 13:09

Comments

0

Just introduce a local variable

StringBuilder sb = new StringBuilder();
foreach(char ch in valor)
{
 var tmp = ch == ',' ? '.' : ch;
 if (char.IsDigit(tmp) || tmp == '.')
 {
 sb.Append(tmp);
 }
}

You can also use the static char.IsDigit() method to check whether a char is a digit or not

You could also do it only with linq:

var sb = new StringBuilder();
sb = valor
 .Select(c => c == ',' ? '.' : c)
 .Where(c => char.IsDigit(c) || c == '.')
 .Aggregate(sb, (sb, c) => sb.Append(c));
answered Jan 28, 2021 at 13:08

Comments

-1

You can try this:


StringBuilder sb = new StringBuilder();
var valor = "google,com1234";
if (valor.Contains(','))
{
 valor = valor.Replace(",", ".");
}
foreach (char ch in valor)
{
 if (ch == '0' || ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5' || ch == '6' || ch == '7' || ch == '8' || ch == '9' || ch == '.')
 {
 sb.Append(ch);
 }
}
answered Jan 28, 2021 at 13:25

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.