C# For Loop with LIST using LINQ - c#

I'm using LINQ and returning a list to my Business Logic Layer. I'mtrying to change one of the values in the list (changing the 'star' rating to an image with the number of stars).
Although the counter (i) appears to be working, the FOR loop is not working correctly. The first time through it stops at the correct IF but then it pops out at the ELSE statement for everything and all values end up with "star0.png." It appears as though I'm not cycling through the list??? Thanks in advance!
for (int i = 0; i < ReviewList.Count; i++)
{
string serviceCode = ReviewList[i].SERVICE.SERVICE_DESC;
if (serviceCode == "*")
{
ReviewList[i].SERVICE.SERVICE_DESC = "star1.png";
}
else if (serviceCode == "**")
{
ReviewList[i].SERVICE.SERVICE_DESC = "star2.png";
}
else if (serviceCode == "***")
{
ReviewList[i].SERVICE.SERVICE_DESC = "star3.png";
}
else if (serviceCode == "****")
{
ReviewList[i].SERVICE.SERVICE_DESC = "star4.png";
}
else
{
ReviewList[i].SERVICE.SERVICE_DESC = "star0.png";
}
}

If all values end up at star0.png, then you are cycling through the list. The fact that the else statement is the only code being executed for each element suggests a logical error -- did you perhaps mean to do something like this?
string serviceCode = ReviewList[i].SERVICE.SERVICE_CODE;

I dont think its an issue of the for loop working properly... your syntax is good and as written will iterate ReviewList.Count # of times.
I would step through and verify the contents of ReviewList first.
Let me know what you find

If you know each item will consist of a number of stars, why not do this?:
for (int i = 0; i < ReviewList.Count; i++)
{
string serviceCode = ReviewList[i].SERVICE.SERVICE_DESC;
ReviewList[i].SERVICE.SERVICE_DESC = "star" + serviceCode.Length + ".png";
}

Protection on double pass and with else condition
for (int i = 0; i < ReviewList.Count; i++)
{
string serviceCode = ReviewList[i].SERVICE.SERVICE_DESC;
if(!serviceCode.Contains(".png")) { // once name set should not be modified
if(serviceCode.Contains("*"))
ReviewList[i].SERVICE.SERVICE_DESC = "star" + serviceCode.Length + ".png";
else
ReviewList[i].SERVICE.SERVICE_DESC = "star0.png";
}
}
alternate LINQ approach
ReviewList.ForEach(rs=>if(!rs.SERVICE.SERVICE_DESC.Contains(".png"))
{ rs.SERVICE.SERVICE_DESC =
"star" + rs.SERVICE.SERVICE_DESC.Length + ".png"});

Related

if statement with string and numerical fields

i have texblocks wn01, wn02, wn03 .... wn15. Every field has text="0"
If field wn01.text 0 or "" i want to enter value of przerzucanie.
If field wn01.text other value, than check next textblock.text
But if statement doesnt enter,
i=1,s=01, string.operator==returned false.
i tried ("wn"+s).Text but is not recognized
private void przerzucanie_wyniku()
{
for (int i = 1; i < 16; i++)
{
string s = i.ToString("00");
if ("wn"+s==null||"wn"+s=="0")
{
"wn"+s.Text = przerzucanie;
break;
}
}
}
"wn" + something else can't ever be null or not start with wn.
What you are doing I think is trying to find the textbox with a specific name instead of concatenating strings. If that is what you need, you have to walk the visual tree to find it. Here an example how to do that in WPF.
This will never be true:
if ("wn"+s==null||"wn"+s=="0")
This will always show "wn*".
You can try:
string w = "wn" + s;
if(w==null||w=="0"){}
answear is:
for (int i = 0; i < 15; i++)
{
TextBlock tb = (TextBlock)s7.Children[i];
if (tb.Text == "0")
{
tb.Text = przerzucanie.ToString();
break;
}

Why is my logic not adding the quotes back to the CSV File for the columns after the First one?

I am using hashmaps to store CSVFile1 and compare it to CSVFile2. CSVFile1 has a column of customers to remove while CSVFile2 has all of the completed data (which has more then 1 column and that is why I am only comparing dataArray2[0]). Once I compare I only rewrite the files that are NOT in the CSVFile1 to a file called CSVFileFinal.
The issue is that some of the data has commas inside of fields and when I read the file it take them out once I try and rewrite. My goal is to rewrite the data with the quotes back around the commas in the fields which I "split" at.
I have managed to get the First column (the most important one) to split and replace the quotes perfectly! But for whatever reason my second loop is messing up and not checking the columns after that correctly. I believe it is simply the placing of my code.
This is the logical statement/placement in question:
if (dataArray2[i].Contains(","))
{
string x = "\"" + dataArray2[i] + "\"";
record = x;
}
I know the logic works because if you look at my entire source code; the code posted works for the first column and works in the 2nd IF statement for If i == 0 meaning if it's the 1st columns. But how or where do I place that to work for the others afterward?
Can anyone help figure out where to place this for the following columns?
It should be a simple copy and pasting of the code I have but I've been unable to figure it out. Thank you!
int count = 0;
while (!CSVFile2.EndOfData)
{
if (!badCustomers.ContainsKey(dataArray2[0]))
{
String record = null;
for(int i = 0; i < dataArray2.Length; i++)
{
if(i == 0)
{
if (dataArray2[i].Contains(","))
{
string x = "\"" + dataArray2[i] + "\"";
record = x;
}
else
record = dataArray2[i];
} else
{
record = record + "," + dataArray2[i];
}
}
count++;
if( count % 50 == 0)
{
Console.WriteLine(count);
}
output.WriteLine(record);
}
dataArray2 = CSVFile2.ReadFields();
}
The above code works but does not consider the later columns after the first one to replace this quotes- this code is what should fix the ones after the first column but for whatever reason it does not. Why?
if (!badCustomers.ContainsKey(dataArray2[0]))
{
String record = null;
for(int i = 0; i < dataArray2.Length; i++)
{
if(i == 0)
{
if (dataArray2[i].Contains(","))
{
string x = "\"" + dataArray2[i] + "\"";
record = x;
}
else
record = dataArray2[i];
} else
{
if (dataArray2[i].Contains(","))
{
string x = "\"" + dataArray2[i] + "\"";
record = x;
}
else
record = record + "," + dataArray2[i];
}
}
What I believe you are asking is for this:
int count = 0;
while (!CSVFile2.EndOfData)
{
if (!badCustomers.ContainsKey(dataArray2[0]))
{
String record = String.Empty;
for(int i = 0; i < dataArray2.Length; i++)
{
if (dataArray2[i].Contains(","))
{
string x = "\"" + dataArray2[i] + "\"";
record += x;
}
else
{
record += dataArray2[i];
}
if (i < dataArray.Length -1)
{
record += ",";
}
}
count++;
if( count % 50 == 0)
{
Console.WriteLine(count);
}
output.WriteLine(record);
}
dataArray2 = CSVFile2.ReadFields();
}
This loops through each line from the input, adding quotes around commas. You may have to tweak it to meet your final needs, but this should be a start.
The reason it was only ever doing it for your first column is the if(i == 0). This means the code would only ever execute for the first iteration (your first column).

For loop reading a file isn't working

I have this:
private void getAccount()
{
string[] acct = File.ReadAllLines(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\Accts.txt");
for (int i = 0; i < acct[line].Length - 1; i++)
{
foreach (char c in acct[line])
{
if (c.ToString() == ":")
{
onPass = true;
i += 1;
}
if (onPass == false) { user += acct[line][i]; }
if (onPass == true) { pass += acct[line][i]; }
}
}
MessageBox.Show("Username is " + user + ". \n\nPassword is " + pass + ".");
onPass = false;
}
The file has this:
minicl55:mypass
However this outputs this:
These are the following problems:
The characters are repeated a lot
only "mmmmmmm" is considered part of the username, everything up until the colon should be part of the username, after is pass
The : is included in the password, it should be ignored completely (except to tell where the username stops and the password starts)
The first time you go through your for loop, i == 0. Then the foreach loop looks at each character in acct[line], but i never changes, so for all the characters prior to :, the acct[line][i] part keeps returning acct[line][0], or "m" 8 times. That's why the username appears to be "mmmmmmmm".
Then the colon is encountered and i is increased by 1. Now onPass == true, so pass ends up having acct[line][1], which is the character "i". This repeats for the rest of the string, so pass appears to be "iiiiiii" (from the colon to the end).
Now we go back to the for loop. Except i has been increased by 1 inside the loop (bad idea) so now the for loop is actually on i == 2. Again the beginning part executes 8 times (once for each character in the username), but always refers to acct[line][2], so the username is "nnnnnnnn". Except onPass is still true, so it gets appended to the password variable. Then you get 7 more "i"'s after i is increased.
The i variable is increased internally and in the for loop again, so next time you're using acct[line][4], which is "c" (8 times), then i is increased by 1 inside the foreach loop and you get acct[line][5] 7 times, which is "l".
So far, password is "iiiiiiinnnnnnnniiiiiiicccccccclllllll". Hopefully you can see the pattern.
You could eliminate some of the looping and complexity, and just use something like: (untested)
private void getAccount()
{
var allAccounts = File.ReadAllLines(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\Accts.txt");
foreach (var account in allAccounts)
{
var pieces = account.Split(':');
MessageBox.Show(string.Format("Username is {0}. \n\nPassword is {1}.", pieces[0], pieces[1]));
}
}
Your outer loop is iterating over each char in acct[line]. Then you do the same in your inner loop, you just express it a little differently.
Please show your variables, but here's another approach:
private void getAccount()
{
string user = "";
string pass = "";
string[] user_pass = new string[0];
var accts = System.IO.File.ReadAllLines(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\Accts.txt");
foreach(var acct in accts)
{
user_pass = acct.Split(':');
}
//Add iteration for multiple lines
if (user_pass.Length > 0)
{
MessageBox.Show("Username is " + user_pass[0] + ". \n\nPassword is " + user_pass[1] + ".");
}
else
{
MessageBox.Show("Chaos: Dogs and Cats Living Together!");
}
}
}
}
Well, I see your first loop gets the length of a specific line whose position doesnt change at all.
for (int i = 0; i < acct[line].Length - 1; i++)
And then you loop through every character of that only line
foreach (char c in acct[line])
The thing is that if your acct[line] has X length, you will loop through the acct[line] X times, hence why the repeated characters. You end up reading the same character X times.
As everyone else has commented/answered, your outer and inner loops are pretty much doing the exact same thing. I rewrote the for-loops so the outer loop loops through each line of the array of strings, and then the inside loop will go through all of the characters in that line.
for (int line = 0; line < acct.Length; line++)
{
int i = 0;
foreach (char c in acct[line])
{
if (c.ToString() == ":")
{
onPass = true;
}
else
{
if (!onPass)
user += acct[line][i];
else
pass += acct[line][i];
}
i++;
}
}
I do suggest however, for your own benefit, if you do NEED to loop through all of the characters to use this for the inner loop:
for (int i = 0; i < acct[line].Length; i++)
{
if (acct[line][i].ToString() == ":")
{
onPass = true;
}
else
{
if (!onPass)
user += acct[line][i];
else
pass += acct[line][i];
}
}
Or better yet replace everything with something simpler, and less prone to being broken by small changes:
for (int line = 0; line < acct.Length; line++)
{
if (acct[line].Contains(":"))
{
string[] parts = acct[line].Split(':');
user = parts[0];
pass = parts[1];
MessageBox.Show("Username is " + user + ". \n\nPassword is " + pass + ".");
}
}

Finding and replacing text in c#

I need to add functionality in my program so that any file imported it will find the text within the "" of the addTestingPageContentText method as seen below. The two values on each line will then be added to a datagridview which has 2 columns so first text in first column then second in the 2nd column. How would i go about Finding the "sometext" ?
addTestingPageContentText("Sometext", "Sometext");
addTestingPageContentText("Sometext2", "Sometext2");
... continues n number of times.
Neither fast nor efficient, but it's easier to understand for those new to regular expressions:
while (!endOfFile)
{
//get the next line of the file
string line = file.readLine();
EDIT: //Trim WhiteSpaces at start
line = line.Trim();
//check for your string
if (line.StartsWith("addTestingPageContentText"))
{
int start1;
int start2;
//get the first something by finding a "
for (start1 = 0; start1 < line.Length; start1++)
{
if (line.Substring(start1, 1) == '"'.ToString())
{
start1++;
break;
}
}
//get the end of the first something
for (start2 = start1; start2 < line.Length; start2++)
{
if (line.Substring(start2, 1) == '"'.ToString())
{
start2--;
break;
}
}
string sometext1 = line.Substring(start1, start2 - start1);
//get the second something by finding a "
for (start1 = start2 + 2; start1 < line.Length; start1++)
{
if (line.Substring(start1, 1) == '"'.ToString())
{
start1++;
break;
}
}
//get the end of the second something
for (start2 = start1; start2 < line.Length; start2++)
{
if (line.Substring(start2, 1) == '"'.ToString())
{
start2--;
break;
}
}
string sometext2 = line.Substring(start1, start2 - start1);
}
}
However I would seriously recommend going through some of the great tutorials out there on the internet. This is quite a good one
The expression "\"[^"]*\"" would find each...

Need help with . string.substring(0, max.Length)

ArgumentOutofBounds Exceptions is thrown all the times inside the ifs in the loop.
In this code I am trying to send two strings between the symbol #2#3.
string1+"#2#3"+string2
Now I try to separate the strings from the symbols by the method substring, but an exception is being thrown over there......
public void seperatePMChattersNames(string TwoNames)
{
string nameOne="";
string nameTwo="";
Console.WriteLine(TwoNames);
for (int i = 0; i < TwoNames.Length; i++)
{
if (TwoNames[i] == '2' && TwoNames[i-1] == '#')///ArgumentOutofRange Exception
{
nameOne = TwoNames.Substring(0, i);
}
if (TwoNames[i] == '#' && TwoNames[i+1] == '3')///ArgumentOutofRange Exception
{
nameTwo = TwoNames.Substring(i+1, TwoNames.Length);
}
}
}
Why is it thrown and how to prevent it?
When i is zero, TwoNames[i - 1] will try to access index -1 of the string - that doesn't exist.
When i is TwoNames.Length - 1, TwoNames[i + 1] will try to access past the end of the string.
Next, when you have found "#3", you're using:
TwoNames.Substring(i+1, TwoNames.Length)
the second parameter of Substring is the length of the substring to take, not the final index. If you just want the rest of the string, you can omit the second argument:
TwoNames.Substring(i+1)
Note that that would include the "3" though - so you probably really want i+2 instead of i+1.
Is there any reason you're not using string.IndexOf(TwoNames, "#2") etc?
If you just want nameOne to be the string before the first "#2" and nameTwo to be the string after the last "#3", you can use:
int endOfOne = TwoNames.IndexOf("#2");
if (endOfOne != -1)
{
nameOne = TwoNames.Substring(0, endOfOne);
}
else
{
// Couldn't find #2... throw exception perhaps?
}
int startOfTwo = TwoNames.LastIndexOf("#3");
if (startOfTwo != -1)
{
// Allow for the "#3" itself
nameTwo = TwoNames.Substring(startOfTwo + 2);
}
else
{
// Couldn't find #3... throw exception perhaps?
}
Another option is to use regular expressions, of course - they add a degree of complexity themselves, but they really are aimed at pattern matching. If you find you need to get even more bits and pieces, they could help.
Your loop starts with i = 0 but in your first if-statement you try access TwoNames[i-1] which tries to access TwoNames[-1]. Clearly this will cause an issue since there is no TwoName[-1].
Your loop should start with i = 1, not 0.
for (int i = 0; i < TwoNames.Length; i++)
should be
for (int i = 1; i < TwoNames.Length-1; i++)
This is the answer
public void seperatePMChattersNames(string TwoNames)
{
Console.WriteLine(TwoNames);
int x = TwoNames.IndexOf("#2");
int y = TwoNames.IndexOf("#3");
string nameone = TwoNames.Substring(0, x);
string nametwo = TwoNames.Substring(y+2);
Console.WriteLine(nameone);
Console.WriteLine(nametwo);
}

Categories