开发者

How can I modify strings using a "For Each" loop?

       'Why doesn't this work?
    Dim myStrings As String() = New String() {string1, string2, string3,}
    For Each s As String In myStrings
        If String.IsNullOrEmpty(s) Then
            s = ""
        End If
        s = "-" & s.Trim() & "-"
    Next

If string1 contains "foo", my intention is that string1 contains "-foo-" after the loop executes. How can I make this work?

I'm guessing that this code makes copies of my strings and modifies those. How can I modify my strings in a loop?

Update I've modified the code to use array indexes:

    ' It still doesn't work.
    Dim myStrings As String() = New String() {string1, string2, string3}
    For i As Integer = 0 To myStrings.Count() - 1
        If String.IsNullOrEmpty(myStringss(i)) Then
            myStringss(i) = ""
        End If
        myStrings(i) = "-" & myStrings(i) & "-"
    Next

The result of this code, referring specifically to the array and index for each element, modifies the array, but my strings still have the same old values. Apparently, initializing an array like this simply copies my values into a new array. How can I modify my original values in a loop?

Emphasis: The array is just for looping purposes. I need to modify string1, string2, and string3 similarly, but once this loop is thru, there is no more use for the array. Oh, and my real code has more than 3 strings.

Let me just say that if I were using a language with more pointers and references, I think I would simply have an array of pointers that poin开发者_如何学运维t to string1, string2, andstring3`. It seems redundant to copy these strings into an array.


This example is in C# but the same principle applies.

string[] myStrings = new string[] { "temp", "temp2", "temp3" };
myStrings = myStrings.Select(x => "-" + x + "-").ToArray();

Output:

"-temp-" "-temp2-" "-temp3-"

Link to the MSDN article: http://msdn.microsoft.com/en-us/library/bb548891.aspx

You can also use a delegate function to check whether the string is empty. Will work on providing a VB solution and edit when I get it

EDIT:

Dim myStrings As String() = _
        {"apple", "banana", "mango", Nothing, "passionfruit", "grape"}
    myStrings = _
        myStrings.Select(Function(fruit) ("-" & fruit & "-")).ToArray()

Output:

"-apple-" "-banana-" "-mango-" "--" "-passionfruit-" "-grape-"

EDIT 2: Does the same thing as the first edit but more readable

Private Function TESTER(ByVal fruit As String) As String
    Return "-" & fruit & "-"
End Function

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)              Handles MyBase.Load
    Dim myStrings As String() = _
       New String() {"apple", "banana", "mango", Nothing, "passionfruit", "grape"}
    myStrings = _
        myStrings.Select(AddressOf TESTER).ToArray()
End Sub


Use a For/Next and in the end, myStrings(i) = s to save the result.


This doesn't work because strings are immutable in .Net - you can't change the value of string1 without explicitly setting string1 to some value, i.e. by doing:

string1 = "Blah";

(Note that you can change the value of the ith string value in the myString array by (for example) using for instead of foreach, however from what I gather this isn't what you want to do)

To solve your problem you are going to need to given a better idea of what problem you are trying to solve, for example you could avoid the need to modify string references in this way by tweaking your interface (see this question for inspiration)


Given your most recent update, what you ask is not possible.

Strings follow value semantics, so anything you do to the string in the array has no effect on the original string. The closest you can come to a referenced string is StringBuilder, but it's not particularly easy to use in the way you want.

You need to take a step back and ask yourself why you're trying to do things this way; in other words, what your actual goal is. Once you share that, perhaps we can find a solution that works.


Depending upon the nature of your collection, you could store unity-length arrays in it rather than strings. If you did that, you would then be able to change the 0th element of each array to update it.

For example, you could have a Dictionary(Of String, String()) which mapped strings onto string arrays. If single-item arrays were stored in the dictionary, you could easily alter the 0th item of any of them without disturbing the dictionary. Note that you should not do that with the dictionary keys, since the dictionary would not be able to search based upon the content of the strings.

BTW, I've sometimes wished for a collection class whose enumerator would return an object which could be used to request an alteration to the collection without jinxing the enumeration. Not sure how to manage such a thing without having to code the collection from scratch.


Iteration variables are immutable. Either use a "classic" loop or another array to store your strings.


It doesn't work because strings are immutable.

Try this instead.

For x As Integer = 0 To myStrings.Length - 1
   myStrings(x) = "new string"
Next

Edit after the update.

I'm not sure it's possible to do this.

Maybe you could just write a function?

string1 = MyFunction(string1)


After your edit I don't think you can do this the way you want to. I think you're better off copying your strings to the array and working with the array. Instead of having string1, string2, etc ... you'd have array[0], array[1], etc ...

Is there anything preventing you from doing so ?


This would be easily encapsulated into a ParamArray of ByRef parameters, but that isn't an option
:-(

So you seem to have to do it manually:

Imports System.Runtime.CompilerServices

Module Module1

Sub Main()
    Dim String1 = "foo"
    Dim String2 = ""
    Dim String3 As String = Nothing
    Dim strings() = New StrongBox(Of String)() {New StrongBox(Of String)(String1), New StrongBox(Of String)(String2), New StrongBox(Of String)(String3)}
    Modify(strings)
    String1 = strings(0).Value
    String2 = strings(1).Value
    String3 = strings(2).Value
    Console.WriteLine("'{0}' '{1}' '{2}'", String1, String2, If(String3, "NOTHING"))
    Console.ReadLine()
End Sub

Sub Modify(ByVal ParamArray myStrings() As StrongBox(Of String))
    For i As Integer = 0 To myStrings.Count() - 1
        If String.IsNullOrEmpty(myStrings(i).Value) Then
            myStrings(i).Value = ""
        End If
        myStrings(i).Value = "-" & myStrings(i).Value & "-"
    Next
End Sub

End Module

EDIT: Note that it is simpler to do something like this (it just doesn't supply anything like what the question is asking for):

Module Module1

Sub Main()
    Dim String1 = "foo"
    Dim String2 = ""
    Dim String3 As String = Nothing
    Modify(String1)
    Modify(String2)
    Modify(String3)
    Console.WriteLine("'{0}' '{1}' '{2}'", String1, String2, If(String3, "NOTHING"))
    Console.ReadLine()
End Sub

Sub Modify(ByRef myString As String)
    If String.IsNullOrEmpty(myString) Then
        myString = ""
    End If
    myString = "-" & myString & "-"
End Sub

End Module


As suggested in @Justin's comment, an alternative is to use a Dictionary and VB's With and ! syntax.

Module Module1

Sub Main()
    Dim strings As New Dictionary(Of String, String)
    With strings
        !String1 = "foo"
        !String2 = ""
        !String3 = Nothing
        Console.WriteLine("'{0}' '{1}' '{2}'", !String1, !String2, If(!String3, "NOTHING"))
        Modify(strings)
        Console.WriteLine("'{0}' '{1}' '{2}'", !String1, !String2, If(!String3, "NOTHING"))
        ModifySome(strings, "String1", "String2")
        Console.WriteLine("'{0}' '{1}' '{2}'", !String1, !String2, If(!String3, "NOTHING"))
    End With
    Console.ReadLine()
End Sub

Sub Modify(ByVal myStrings As Dictionary(Of String, String))
    ModifySome(myStrings, myStrings.Keys.ToArray)
End Sub

Sub ModifySome(ByVal myStrings As Dictionary(Of String, String), ByVal ParamArray someStrings() As String)
    For Each s As String In someStrings
        If String.IsNullOrEmpty(myStrings(s)) Then
            myStrings(s) = ""
        End If
        myStrings(s) = "-" & myStrings(s) & "-"
    Next
End Sub

End Module
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜