Checking last element in string and removing c# - c#

I have a list of strings that I am wanting to remove the , from the end of the string. I looked up online how to check to see if you are at the last index of a string and on how to remove the last index from the string. But when I do the following, it still does not seem to remove the ,.
List<string> groceryList = "apple, fruit, banana, carrots, mango";
var x = "buy ";
var y = groceryList;
foreach (var item in y)
{
x = x + item + ", ";
if (item == y.Last()){
x.Remove(x.Length - 1); }
}
I even tried x.Remove(x.Length - 2) thinking it would hit the , but the variable x still contains the , at the end of the string. Also I tried x.Remove(x.Last()) but it still does not remove the , after mango. So it will show mango, instead of mango.

You have to reassign the value of the x. The following code should give you the desired result.
x = x.Remove(x.Length - 2, 2);

You're better off avoiding the dangling comma in the first place.
Try this:
List<string> groceryList = new List<string>() { "apple", "fruit", "banana", "carrots", "mango" };
string x = $"buy {String.Join(", ", groceryList)}";
That gives me buy apple, fruit, banana, carrots, mango.
If you want to build it yourself, then an for loop is the way to go:
for (int i = 0; i < groceryList.Count; i++)
{
x += groceryList[i];
if (i < groceryList.Count - 1)
x += ", ";
}
Or an enumerator:
var e = groceryList.GetEnumerator();
if (e.MoveNext())
{
while (true)
{
x += e.Current;
if (e.MoveNext())
x += ", ";
else
break;
}
}

Related

StringBuilder formatting with list

I am having problems formatting a list with stringbuilder to output the way I need it. Basically need my list to drop a line every two values. For example I loop through a series of text boxes and add entered text to the list. I then loop through the list and print or copy to clipboard the data:
List<string> listValues = new List<string>();
StringBuilder value = new StringBuilder();
foreach (TextBox x in controlGrid.Children.OfType<TextBox>())
{
if (x.Text.Length > 0)
{
listValues.Add(x.Text);
}
}
for (int i = 0; i < listValues.Count; i++)
{
// formating code w/ listValues[i];
}
I need it to format as such:
listValues[0] + " " + listValues[1]
listValues[2] + " " + listValues[3]
listValues[4] + " " + listValues[5]
which to the user would paste like:
1 foo
2 fooa
3 foob
I have searched around for a good bit and can't find a similar result so if the easy answer is out there I apologize for the repeat.
Thanks
Do you even need the list? Just go straight into the StringBuilder like this?
bool first = true;
StringBuilder value = new StringBuilder();
foreach (TextBox x in controlGrid.Children.OfType<TextBox>())
{
if (x.Text.Length > 0)
{
value.Append(first ? x.Text : " " + x.Text + "\r\n");
first = !first;
}
}
Console.WriteLine(value.ToString());
You could use LINQ for the purpose.
var result = listValues.Select((x, i) => new { Index = i, Value = x })
.GroupBy(x => x.Index / 2)
.Select(x => string.Join(" ", x.Select(c => c.Value)));
Sample Input
1
Foo
2
fooa
3
foob
Output
1 Foo
2 fooa
3 foob

Replace substring from the listbox (WindowsForms)

I have attached in my listbox ( lb1 ) a character to the previous item. The letter A is seperated by a comma. Is it even possible to replace the letter in this line
(A --> B)? How can this be solved? The result in the listbox( lb2 ) should look as shown below.
if (listBox1.Items.Cast<string>().Contains("someText"))
{
int a = listBox1.Items.IndexOf("someText");
listBox1.Items.RemoveAt(a);
listBox1.Items.Insert(a, "newText");
}
Here is a code snippet for your new problem mikee:
You need to iterate through the items of the list box, search for a match, and replace the detected matches:
string search = "A";
string replace = "B";
for(int i = 0; i < lb1.Items.Count; i++)
{
if(lb1.Items[i].ToString().EndsWith(search))
{
string item = lb1.Items[i].ToString().Replace(search, replace);
lb1.Items[i] = item;
}
}
Edit
Please note that, the preceding snippet will change all the A characters in the string with B not only the last one. So if you have a list item say JONATHAN, A, the preceding code will change it to JONBTHBN, B. To avoid that you could do:
Solution 1:
for (int i = 0; i < lb1.Items.Count; i++)
{
if (lb1.Items[i].ToString().EndsWith(search))
{
int indx = lb1.Items[i].ToString().LastIndexOf(search);
string item = lb1.Items[i].ToString().Substring(0, indx) + replace;
lb1.Items[i] = item;
}
}
Solution 2:
If all of your list items are comma separated strings like the image above, then you could do:
for (int i = 0; i < lb1.Items.Count; i++)
{
if (lb1.Items[i].ToString().EndsWith(search))
{
var arr = lb1.Items[i].ToString().Split(',');
arr[arr.Length - 1] = replace;
lb1.Items[i] = string.Join(", ", arr);
}
}
Sorry for any inconvenience mikee.
Good luck.

Add all chars of a string to a list but merge numbers to one entry C#

You have given a string like "(32+5)*20" and you need to create a list with all chars, but need to merge the numbers to one entry like "32" and "20". How to do it?
I have already tried
string formel = "(32+5)*20";
char[] zeichen = formel.ToCharArray();
var liste = new List<string>();
for(int i = 0; i < zeichen.Length ; i++)
{
if(Char.IsNumber(zeichen[i]) && formel.Substring(i, i + 1).Any(char.IsNumber))
{
liste.Add(zeichen[i].ToString() + zeichen[i+1].ToString());
}
else
{
liste.Add(zeichen[i].ToString());
}
}
You could use regex to return the groups of numbers:
var formel = "(32+5)*20";
var pattern = "([0-9]+)";
var match = Regex.Match(formel, pattern);
and then use
match.Groups
The list as posted will still contain the same number of elements as the string did, since you added to it on every loop iteration. To "merge" into one entry, you need to not add on some iterations, but instead add that digit to the previous number.
This is easier if you check if the previous item was a number, rather than the next.
for (int i = 0; i < zeichen.Length; i++)
{
if (i > 0 && Char.IsNumber(zeichen[i]) && Char.IsNumber(zeichen[i - 1])) // if got a number, and had a number before
{
// Then dont Add to the list, instead add to the number/string
liste[list.Count - 1] += zeichen[i];
//liste.Add(zeichen[i].ToString() + zeichen[i + 1].ToString());
}
else
liste.Add(zeichen[i].ToString());
}
// "(", "32", "+", "5", ")", "*", "20"
You can do it by using Regex and LINQ
var dateText = "(32 + 5) * 20";
string splitPattern = #"[^\d]";
var result = Regex.Split(dateText, splitPattern).Where(x=>x!="");
I hope this will help you #Janic

Replacing word in different ways

For first I have phrase like ice z comp. In the output I need List<string> which have this word with dashes for example like this: ice-z comp, ice z-comp, ice-z-comp
For now I have this:
var synonymFromSynonym = new List<string>();
var countOfSpaces = word.Count(Char.IsWhiteSpace);
for (int x = 0; x < countOfSpaces; x++)
{
// What here for my output ?
}
The problem can be solved using the following implementation. First, the input is split into the individual words.
var Words = word.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).ToArray();
Then, the words are assembled again, considering two cases, namely whether the connection is done with a space or with a hyphen. This can be done recursively as follows, where a call like GenerateResult("", 0 ) would start the calculation.
List<string> Result = new List<string>();
void GenerateResult(string Intermediate, int Position)
{
if (Position == Words.Count() - 1) // base case, nothing to append
{
Result.Add(Intermadiate);
}
else
{
GenerateResult( Intermediate + " ", Position + 1 ); // space case
GenerateResult( Intermediate + "-", Position + 1 ); // hyphen case
}
}

String split by every 3 words

I've got a problem. I need to split my every string like this:
For example:
"Economic drive without restrictions"
I need array with sub string like that:
"Economic drive without"
"drive without restrictions"
For now i have this:
List<string> myStrings = new List<string>();
foreach(var text in INPUT_TEXT) //here is Economic drive without restrictions
{
myStrings.DefaultIfEmpty();
var textSplitted = text.Split(new char[] { ' ' });
int j = 0;
foreach(var textSplit in textSplitted)
{
int i = 0 + j;
string threeWords = "";
while(i != 3 + j)
{
if (i >= textSplitted.Count()) break;
threeWords = threeWords + " " + textSplitted[i];
i++;
}
myStrings.Add(threeWords);
j++;
}
}
You could use this LINQ query:
string text = "Economic drive without restrictions";
string[] words = text.Split();
List<string> myStrings = words
.Where((word, index) => index + 3 <= words.Length)
.Select((word, index) => String.Join(" ", words.Skip(index).Take(3)))
.ToList();
Because others commented that it would be better to show a loop version since OP is learning this language, here is a version that uses no LINQ at all:
List<string> myStrings = new List<string>();
for (int index = 0; index + 3 <= words.Length; index++)
{
string[] slice = new string[3];
Array.Copy(words, index, slice, 0, 3);
myStrings.Add(String.Join(" ", slice));
}
I try to give a simple solution. So i hope you can better understand it.
List<string> myStrings = new List<string>();
string input = "Economic drive without restrictions";
var allWords = input.Split(new char[] {' '});
for (int i = 0; i < allWords.Length - 2; i++)
{
var textSplitted = allWords.Skip(i).Take(3);
string threeString = string.Join(" ", textSplitted);
myStrings.Add(threeString);
}
foreach (var myString in myStrings)
{
Console.WriteLine(myString);
}
The method Take(n) is from Linq. It takes the first n elements of the given array. for example if you have an array a,b,c,d,e then Take(3) will give you a new array a,b,c.
The method Skip(n) is from Linq. It gives you the new array by skipping first n elements. given array a,b,c,d,e then Skip(1) will return b,c,d,e. as you can see it skipped the first elements.
Now with this two methods you can move on array 3 by 3 and get the words you want.
Just for comparative purposes, here's another solution that doesn't use Linq:
string[] words = INPUT_TEXT.Split();
List<string> myStrings = new List<string>();
for (int i = 0; i < words.Length - 2; ++i)
myStrings.Add(string.Join(" ", words[i], words[i+1], words[i+2]));
Or using ArraySegment<string>:
string[] words = INPUT_TEXT.Split();
List<string> myStrings = new List<string>();
for (int i = 0; i < words.Length - 2; ++i)
myStrings.Add(string.Join(" ", new ArraySegment<string>(words, i, 3)));
I would use one of the methods described here ; for instance the following that takes the elements 3 by 3.
var groups = myStrings.Select((p, index) => new {p,index})
.GroupBy(a =>a.index/3);
Warning, it is not the most memory efficient, if you start parsing big strings, it might blow up on you. Try and observe.
Then you only need to handle the last element. If it has less than 3 strings, fill it up from the left.

Categories

Resources