C# - Concatenate inside a loop - c#

Is it possible to concatenate inside a C# loop? Below is my sample code:
for (int i = 0; i <= metricCount; i++)
{
if (m.metrictNumber == i)
{
aggrgt.Add(new PlainBrgDataSummaryChartAggrgt
{
scoreWk6 = scoresPerDuration.scoresPerDuration.scoreWk6.metricScore1,
scoreWk5 = scoresPerDuration.scoresPerDuration.scoreWk5.metricScore1,
scoreWk4 = scoresPerDuration.scoresPerDuration.scoreWk4.metricScore1,
scoreWk3 = scoresPerDuration.scoresPerDuration.scoreWk3.metricScore1,
scoreWk2 = scoresPerDuration.scoresPerDuration.scoreWk2.metricScore1,
scoreWk1 = scoresPerDuration.scoresPerDuration.scoreWk1.metricScore1
});
}
}
What I want is to concatenate metricScore1.
Here's what I tried:
scoreWk6 = scoresPerDuration.scoresPerDuration.scoreWk6.metricScore + i,
Is that possible?

You cannot. If you see numbers in variable names, it's probably wrong. Numbering your variables means you should have used a container type. Either an array or a list or anything else that supports going through it with a loop index or foreach.
So the answer is no. No, you cannot. You should change the types holding your data.

Related

How to reverse string in C# [duplicate]

I didn't get the problem - I was trying to do a simple action:
for(i = x.Length-1, j = 0 ; i >= 0 ; i--, j++)
{
backx[j] = x[i];
}
Both are declared:
String x;
String backx;
What is the problem ? It says the error in the title...
If there is a problem - is there another way to do that?
The result (As the name 'backx' hints) is that backx will contain the string X backwards.
P.S. x is not empty - it contains a substring from another string.
Strings are immutable: you can retrieve the character at a certain position, but you cannot change the character to a new one directly.
Instead you'll have to build a new string with the change. There are several ways to do this, but StringBuilder does the job in a similar fashion to what you already have:
StringBuilder sb = new StringBuilder(backx);
sb[j] = x[i];
backx = sb.ToString();
EDIT: If you take a look at the string public facing API, you'll see this indexer:
public char this[int index] { get; }
This shows that you can "get" a value, but because no "set" is available, you cannot assign values to that indexer.
EDITx2: If you're looking for a way to reverse a string, there are a few different ways, but here's one example with an explanation as to how it works: http://www.dotnetperls.com/reverse-string
String is immutable in .NET - this is why you get the error.
You can get a reverse string with LINQ:
string x = "abcd";
string backx = new string(x.Reverse().ToArray());
Console.WriteLine(backx); // output: "dcba"
String are immuatable. You have convert to Char Array and then you would be able to modify.
Or you can use StringBuilder.
for example
char[] wordArray = word.ToCharArray();
In C# strings are immutable. You cannot "set" Xth character to whatever you want. If yo uwant to construct a new string, or be able to "edit" a string, use i.e. StringBuilder class.
Strings are immutable in C#. You can read more about it here: http://msdn.microsoft.com/en-us/library/362314fe.aspx
Both the variables you have are string while you are treating them as if they were arrays (well, they are). Of course it is a valid statement to access characters from a string through this mechanism, you cannot really assign it that way.
Since you are trying to reverse a string, do take a look at this post. It has lot of information.
public static string ReverseName( string theName)
{
string revName = string.Empty;
foreach (char a in theName)
{
revName = a + revName;
}
return revName;
}
This is simple and does not involve arrays directly.
The code below simply swaps the index of each char in the string which enables you to only have to iterate half way through the original string which is pretty efficient if you're dealing with a lot of characters. The result is the original string reversed. I tested this with a string consisting of 100 characters and it executed in 0.0000021 seconds.
private string ReverseString(string testString)
{
int j = testString.Length - 1;
char[] charArray = new char[testString.Length];
for (int i = 0; i <= j; i++)
{
if (i != j)
{
charArray[i] = testString[j];
charArray[j] = testString[i];
}
j--;
}
return new string(charArray);
}
In case you need to replace e.g. index 2 in string use this (it is ugly, but working and is easily maintainbable)
V1 - you know what you want to put their. Here you saying in pseudocode string[2] = 'R';
row3String.Replace(row3String[2], 'R');
V2 - you need to put their char R or char Y. Here string[2] = 'R' if was 'Y' or if was not stay 'Y' (this one line if needs some form of else)
row3String.Replace(row3String[2], row3String[2].Equals('Y') ? 'R' : 'Y');

changing the value of certain elements of a list

I am looping through a list and would like to add multiple occurrences, should I find them.
so far I have,
public struct optionsSort
{
public string name;
public string date;
public double strike;
public string callPut;
public double size;
public string isin;
}
List<List<optionsSort>> stocks = new List<List<optionsSort>>();
optionsSort tempStock1 = new optionsSort();
List<optionsSort> posCheckOptions = new List<optionsSort>();
then some code, then,
for(int k = 0; k<posCheckOptions.Count; k++)
{
for(int l = 0; l<posCheckOptions[l].Count; l++)
{
if(posCheckOptions[l+1] == null)
{
//finished the iteration
break;
}
else if
(posCheckOptions[k][l + 1].date == posCheckOptions[k][l].date
&& posCheckOptions[k][l + 1].strike == posCheckOptions[k][l].strike
&& posCheckOptions[k][l + 1].callPut == posCheckOptions[k][l].callPut)
{
posCheckOptions[k][l].size = posCheckOptions[k][l].size
+ posCheckOptions[k][l + 1].size;
}
}
}
Basicly, Im looking forward from the start of the list. asking the question, are certain elements of the list at i+1 the same as i, if so, add those elements to i and delete the entire row.
i get this error
"Error 1 Cannot modify the return value of 'System.Collections.Generic.List.this[int]' because it is not a variable C:\Users\WindowsFormsApplication1\WindowsFormsApplication1\ReadCSV.cs 890 25 WindowsFormsApplication1
"
Many Thanks for looking.
I believe your problem is that you are using a mutable struct. Mutable structs are evil.
The simplest solution is to change optionsSort to a class. That should fix the error message.
To explain the error message, when you call posCheckOptions[k][l], since optionsSort is a struct, it returns a copy of the value in the list. When you change size, it will update the copy, but not the one in the list. The copy would then be discarded. The compiler recognizes this and stops you.
I recommend you read up on the differences between reference types and value types.

Add TextBox.Text to a list using a for loop

I am trying to take the values in the textboxes, named sequentially from 0-9, and add that to a List using a for loop. I am having problems with the syntax or something.
here is what I have now.
for (int i = 0; i <= amt.Count(); i++)
{
amt[i] = int.Parse(amtBox[i].Text);
}
The error is that amtBox doesnt exist in the current context.
My problem is within the loop where i have amtBox[i].Text. I have tried this several ways and VS always throws an error. I have tried "amtBox" + i and that compiles but then causes an error when I try to do something with it and says "data is of wrong type".
I am new to C# and come from PHP so maybe that is why I think this approach will work. PHP doesnt care about data types where C# really does. I have done this exact thing in PHP many times without any issue.
Any suggestions on another way to do this are appreciated as I am probably coming at this all wrong.
Thanks
One solution would be to declare an array and assign amtBox'es to the individual indexes in the array and then you can iterate on that array.
var amtBoxes = new TextBox[] { amtBox0, amtBox1, .... };
for (int i = 0; i <= amt.Count(); i++)
{
amt[i] = int.Parse(amtBoxes[i].Text);
}
If you end up needing to iterate on your TextBox controls in other places I would consider making the array an instance member of your object.
I suppose that your textbox are named "amtBox" + a number.
(The Name property is "amtBox1" as an example)
In this case you could use
Control[] t = Controls.Find("amtBox" + i, false);
for a code like this
for (int i = 0; i <= amt.Count(); i++)
{
Control[] t = Controls.Find("amtBox" + i, false);
if(t != null && t.Length > 0)
{
amt[i] = int.Parse(t[0].Text);
}
}
My understanding is that you have text boxes named amtBox1, amtBox2, etc., and what you are trying to do is sequence through them. As you point out, this is very easy in PHP. It is possible to do what you're suggesting using reflection, but that is expensive and, in any event, there's probably a better way to do what you're looking for.
You could put all of your amount boxes into an array, and then what you have would work:
var amtBoxes = new[] {
amtBox1,
amtBox2,
amtBox3
}

c# - concatenation and properties of TextBox

I'm trying to use something like this:
for (int i = 0; i < 40; i++)
{
string x + i = TextBox + i.Text;
}
Is there any solution for this? I want to use i as an index as if I had an array of TextBox. How can I achieve a textbox's Text property like this?
I want to create for example a string named x1,x2,x3,x4... and value of x1 = TextBox1.Text.
But I could not :(
I have TextBox1,2,3...40 and I just want to pass their text values to new string or string list ex. like x1 = TextBox1.Text, x2 = TextBox2.Text; ..... :(
You're trying to get the Text property from a collection of TextBox - which, by the way, you haven't shown us how you're getting. It's possible that you don't even have an array of TextBox.
If you do, you'd use code like this (note that SomeCodeToGetTextBoxArray() needs to be defined by you):
TextBox[] myTextBoxes = SomeCodeToGetTextBoxArray();
var arrayLength = myTextBoxes.Length;
String[] x = new String[arrayLength];
for (int i = 0; i < arrayLength; i++)
{
x[i] = myTextBoxes[i].Text;
}
What you're looking to do is have a reference to a local variable, field, or property by it's string name that you generate at runtime. The only way to do what you want is to use reflection.
There are different ways to do this depending on if the variable is locally scoped, a field member, or a property member.
Reflection - LocalVariableInfo - FieldInfo - PropertyInfo
Note that while that would be the answer to your question, it is probably better to use an array (or List<T>) and use indexes. Though, it is really impossible to know without knowing what you are trying to do fully (not just in your little snippet). But, it's more likely that an array (or List<T>) is the more correct solution.

Where is the right place to re-initialize variables in a loop?

Which is the right approach and why?
string initializeme = string.Empty;
StringBuilder AppendToMe = new StringBuilder();
for(int i=0; i < 10; i++)
{
initializeme = string.Empty; //Is this the right place to initialize?
if(expressionThatEvalsTrue)
initializeme = SomeMethodReturningString();
if(!string.IsNullOrEmpty(initializeme)
AppendToMe.Append(initializeme);
}
or
string initializeme = string.Empty;
StringBuilder AppendToMe = new StringBuilder();
for(int i=0; i < 10; i++)
{
if(expressionThatEvalsTrue)
initializeme = SomeMethodReturningString();
if(!string.IsNullOrEmpty(initializeme)
AppendToMe.Append(initializeme);
initializeme = string.Empty; //Is this the right place to initialize?
}
There are three factors here:
Are you going to capture the variable in the loop using a lambda expression or anonymous method? If so, do you want to capture a single variable, or a separate one per iteration?
Do you need the value after the loop?
Do you need the current value in the next iteration of the loop?
I generally declare variables in the smallest possible scope, and try to initialize them immediately:
for(int i=0; i < 10; i++)
{
string initializeme = expression ? SomeMethodReturningString() : "";
Console.WriteLine(initializeme);
}
I prefer this:
for(int i=0; i<10; i++)
{
var initializeme = expression
? SomeMethodReturningString()
: string.Empty;
Console.WriteLine(initializeme);
}
The reason I prefer this style is that it is self-contained: the variable is only set in one place. Doing it inside the loop reduces the scope of the variable as well, which is also to be preferred. I like the use of the extra variable in this case because using the ternary operator as a parameter, IMO, makes the function call less readable.
Modern compilers convert code to static single assignment form, in which every variable is assigned exactly once, so there's no excuse not to declare new variables whenever convenient, as in each iteration of a loop.
The best way to do it is like this:
for (int i = 0; i < 10; i++)
{
string initializeme = string.Empty;
if (expressionThatEvalsFalse)
initializeme = SomeMethodReturningString();
Console.WriteLine(initializeme);
}
If you use initializeme outside the loop, you'll need to declare it outside the loop.
I would declare the variable inside the loop and assume that the compiler is smart enough not to create slow code from this:
for(int i=0; i<10; i++)
{
string initializeme = string.Empty;
if(expressionThatEvalsFalse)
initializeme = SomeMethodReturningString();
Console.WriteLine(initializeme);
}
Will you be using this variable after the loop completes? The only difference I can see is that if you need to retain the last value of that variable, the first does while the second does not.
in the code snippets i can see no reason to initialize in the first place. The two snipperts will differ after the loop where the initializeme is either potentially initialized to a value (snippet one) or empty string (snippet two. So the premis for the below code is that you only need the initializeme in the loop
StringBuilder AppendToMe = new StringBuilder();
for(int i=0; i < 10; i++)
{
if(expressionThatEvalsTrue)
AppendToMe.Append(SomeMethodReturningString());
}
Neither in my opinion. In both cases I would do the following.
Replace
initializeme = string.Empty; //Is this the right place to initialize?
if(expressionThatEvalsTrue)
initializeme = SomeMethodReturningString();
With
initializeme = expressionThatEvalsTrue ?
SomeMethodReturningString() : string.Empty
This way if your expressionThatEvalsTrue is true you get the string from the method, othewise it will be set to blank.

Categories