1

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.

2
  • nicest / most elegant solution for such a simple case that requires only a single Select? Commented May 22, 2013 at 20:32
  • Well, I tried to create as simplistic an example as possible for the sake of illustration of my point / question... The bigger question was that I assumed the ForEach would be faster and yet did not work as expected at all and I'm just trying to understand as much about this as possible.... Commented May 22, 2013 at 20:40

3 Answers 3

3

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
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the additional example with the For loop. As for the LINQ ForEach method - It will not work because LINQ is only looking at the data for the sake of querying rather than has the functionality within it to update it? Am I understanding you correctly? Forgive my ignorance... I'm just trying to learn as much as possible here to become a better programmer....
@JohnBustos: Yes, data coming into the ForEach method is meant to be immutable, similar to a regular for..each loop. Suppose you have the above as For Each s As String In lst, you would not be able to change s there.
@JohnBustos: Keep in mind that your ForEach is actually calling a method of a generic list, not LINQ. It exists in .NET 2.0.
1

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.

1 Comment

Thanks, @Joel, that actually does make perfect sense... Between that and Neolisk giving the example of a simple, normal, For Each loop, it makes perfect sense and just seems kinda silly now!! - I guess that's a good thing :)
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.