I have a List of string values and and some of the values contains xxx or XXX in front.
xxxRed
xxxYellow
xxxxCareful with that axe Eugene!
xxxxxxdedicum aceasta frumoasa Melodia
xxxxLeaders
xxxxWorking Around - titles
XXXXXNothing To Fear
xxxxAvoiding standards
xxxFirst Aid
List<string> lstTitles = new List<string>();
This is what I have tried
for (int i=0; i < lstTitles.Count; i++)
{
string title = lstTitles[i].ToLower().Trim();
if (title[0] == 'x')
{
lstTitles.Remove(lstTitles[i]);
}
}
Problem I have is that only some of the values are removed but not all of them.
Is there perhaps a better way of removing these values?
Use RemoveAll method
lstTitles.RemoveAll(s => s[0] == 'x' || s[0] == 'X');
and you may want to use StartsWith instead of comparing first char.
lstTitles.RemoveAll(s => s.StartsWith("x",StringComparison.InvariantCultureIgnoreCase));
Problem I have is that Only some of the values are removed but not all of them.
Because you're skipping items. When you call Remove(), the next item will be at index i, but you'll increase i in the next loop.
It can be solved by iterating over a copy of the list, and removing unwanted items in the original:
foreach (var item in lstTitles.ToList())
{
if (item.StartsWith("x", StringComparison.InvariantCultureIgnoreCase))
{
lstTitles.Remove(item);
}
}
Though this involves creating a copy of the list, which isn't really useful, as well as calling Remove() which itself is far from performant.
So you could invert your for-loop, to remove the last items first which doesn't change the indexing for unprocessed items:
for (int i = lstTitles.Count - 1; i > 0; i--)
{
if (lstTitles[i].StartsWith("x", StringComparison.InvariantCultureIgnoreCase))
{
lstTitles.RemoveAt(i);
}
}
But as @I4V points out, all of this logic already is in List<T>.RemoveAll(), which is nicer to read and probably optimized for some edge cases, so there's little use to hand-code it again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With