stringvb.netbyref

Override List(of String) Elements in a Sub


The following example is simplified. In my project I have a big List(of String) where I have to do some manipulations on the strings. For this I created a Sub where I do the manipulation and that should rewrite the Elements of the List(of String).

Module Module1
    Sub Main()
        Dim myList As List(Of String) = New List(Of String)
        myList.Add("1Tom")
        myList.Add("2Lisa")
        'Now I want apply a function to the List. As an example I created one that removes the first Letteer
        RemoveFirstChar(myList)
        For Each str As String In myList
            Console.Write(str)
        Next
        Console.Read()
    End Sub

    Sub RemoveFirstChar(ByRef myList As List(Of String))
        For Each str As String In myList
            str = str.Substring(2)
        Next
    End Sub
End Module

The string manipulation itself within the Sub works but it is not written into the initial List-Object. I actually thought that using ByRef would do this. Is it possible to do it this way and I just have a mistake or do I have to create a new List(of String) using a function and override the inital object. Like:

myList = foo(myList)

If both would work, what is more efficient? Since I have to do this on a List(of Strings) wiht few hundret thousand elements.


Solution

  • You have to use a For-loop, you can't modify the string with a For Each:

    Sub RemoveFirstChar(ByRef myList As List(Of String))
        For i As Integer = 0 To myList.Count - 1
            Dim str As String = myList(i)
            myList(i) = str.Substring(2)
        Next
    End Sub
    

    You could modify the For Each object, but since strings are immutable you can't modify them but you need to replace them. You can't replace the whole object in a For Each, hence you need For.

    But note that this will remove the first two chars(indexes are zero based in .NET) and also doesn't check if the string-length is >= 2. So this seems to be what you need:

    myList(i) = If(str.Length >= 1, str.Substring(1), str)