Reputation: 19574
I have the following List(Of String)
defined in my program:
MyList:
1Test
2test
3
4Test
5
I would like to remove the word "Test" (regardless of capitalization) from each item in the list if it exists.
I know I can accomplish this using the following LINQ statment:
MyList = (From MyEntry As String In MyList
Select UCase(MyEntry).Replace("TEST", "")).ToList
To get the final result:
MyList:
1
2
3
4
5
Now, just for the sake of learning Linq, I wanted to try doing it using different commands (and maybe even benchmarking them just to see which could be the best / most efficient). So I wanted to try:
MyList.ForEach(Function(MyEntry As String) MyEntry = UCase(MyEntry).Replace("TEST", ""))
But it doesn't seem to update the list.
I'm assuming this is because ForEach
doesn't replace the data being iterated over, but I wanted to hear from any LINQ experts out there what your thoughts are / what you would suggest as being the nicest / most elegant solution to accomplish this.
Upvotes: 1
Views: 4150
Reputation: 71
Try this
static void Main(string[] args)
{
List<string> lst = new List<string>() { "1Test", "2Test","33", "3test" };
var q = from T in lst
select new
{
NewT = T.ToUpper().Replace("TEST", "")
};
Console.WriteLine("");
int i = 0;
foreach (var str in q.ToList())
{
lst[i++] = str.NewT;
Console.WriteLine(str.NewT);
}
Console.Read();
}
and here is the results
1
2
33
3
Upvotes: 0
Reputation: 28764
It doesn't update the list because you're not updating the list. Your function is getting a variable called MyEntry
passed into it, and you're overwriting the variable, but doing nothing to put the new value back into the list. And it's a good thing, too, because if you did put the modified value back into the list, you'd probably get an exception about the collection being modified during enumeration.
I would stick with your original version that replaces the entire list with a modified version, or else do a normal for loop rather than a foreach loop.
Upvotes: 1
Reputation: 26454
LINQ is meant for reading data, which you can act upon. It is not used to change data. You can, however, read the old set, process, get the new set, and then overwrite the old set with it, but it will not be faster than just working against the original List via a For loop. So your best bet is probably this:
Dim lst As New List(Of String)({"1Test", "2test", "3", "4Test", "5"})
For i = 0 To lst.Count - 1
lst(i) = Regex.Replace(lst(i), "test", "", RegexOptions.IgnoreCase)
Next
Upvotes: 3