John Bustos
John Bustos

Reputation: 19574

Linq - Replace string within a List(of String)

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

Answers (3)

Mike
Mike

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

Joel Mueller
Joel Mueller

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

Victor Zakharov
Victor Zakharov

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

Related Questions