For循环:循环时改变循环条件

For Loop: changing the loop condition while it is looping

我想做的是用"Bb"替换字符串中的所有'A'。但它只会循环使用原始字符串而不是新字符串。

例如:

AAA
BbAA
BbBbA

它停在那里,因为原始字符串的长度只有 3。它只读取到第 3 个索引,而不是其余的。

    Dim txt As String
    txt = output_text.Text

    Dim a As String = a_equi.Text

    Dim index As Integer = txt.Length - 1
    Dim output As String = ""

    For i = 0 To index
        If (txt(i) = TextBox1.Text) Then
            output = txt.Remove(i, 1).Insert(i, a)
            txt = output
            TextBox2.Text += txt + Environment.NewLine

        End If
    Next
End Sub

检查您的评论以获得更好的解决方案,但为了将来参考,如果您的条件将发生变化并且您希望考虑该变化,则您应该使用 while 循环而不是 for 循环。

我在下面做了一个简单的例子来帮助你理解。如果您尝试使用 for 循环执行相同操作,您只会打印 "one" "two" 和 "three",因为 for 循环不会 'see' vals已更改

    Dim vals As New List(Of String)
    vals.Add("one")
    vals.Add("two")
    vals.Add("three")

    Dim i As Integer = 0
    While i < vals.Count
        Console.WriteLine(vals(i))
        If vals(i) = "two" Then
            vals.Add("four")
            vals.Add("five")
        End If
        i += 1
    End While

我打算写一个 while 循环来回答你的问题,但意识到(在其他人的帮助下)你可以 .replace(x,y)

Output.Text = Input.Text.Replace("A", "Bb")

'Input = N A T O
'Output = N Bb T O

编辑: 可能有更好的选择,但我很快记下了这个循环,希望它能有所帮助。

你说了你的新话,还没有完全理解while loops。因此,如果您不了解 functions 或如何向他们 pass arguments,我建议您也查一下。

这是您的事件,可以是按钮单击或文本框文本更改。

'Cut & Paste into an Event (Change textboxes to whatever you have input/output)

    Dim Input As String = textbox1.Text

    Do While Input.Contains("A")

        Input = ChangeString(Input, "A", "Bb")

        ' Do whatever you like with each return of ChangeString() here

    Loop

    textbox2.Text = Input

这是您的函数,有 3 个参数和一个 Return 值,可以在您的代码中调用

' Cut & Paste into Code somewhere (not inside another sub/Function)
Private Function ChangeString(Input As String, LookFor As Char, ReplaceWith As String)

    Dim Output As String = Nothing
    Dim cFlag As Boolean = False

    For i As Integer = 0 To Input.Length - 1
        Dim c As Char = Input(i)

        If (c = LookFor) AndAlso (cFlag = False) Then
            Output += ReplaceWith
            cFlag = True
        Else
            Output += c
        End If

    Next

    Console.WriteLine("Output: " & Output)
    Return Output

End Function

如果您确实想一个一个地替换而不是使用 Replace 函数,您可以使用 while 循环查找您的搜索索引 character/string,然后 replace/insert指数.

Sub Main()
    Dim a As String = String.Empty
    Dim b As String = String.Empty
    Dim c As String = String.Empty
    Dim d As Int32 = -1
    Console.Write("Whole string: ")
    a = Console.ReadLine()
    Console.Write("Replace: ")
    b = Console.ReadLine()
    Console.Write("Replace with: ")
    c = Console.ReadLine()

    d = a.IndexOf(b)
    While d > -1
        a = a.Remove(d, b.Length)
        a = a.Insert(d, c)
        d = a.LastIndexOf(b)
    End While
    Console.WriteLine("Finished string: " & a)
    Console.ReadLine()
End Sub

输出将如下所示:

Whole string: This is A string for replAcing chArActers.
Replace: A
Replace with: Bb
Finished string: This is Bb string for replBbcing chBbrBbcters.

我认为这让我们需要寻找 String.ReplaceFirst 函数。由于没有,我们可以只编写该函数。然后调用它的代码变得更具可读性,因为它很快就会明白它在做什么(从函数的名称。)

Public Function ReplaceFirst(searched As String, target As String, replacement As String) As String

    'This input validation is just for completeness.
    'It's not strictly necessary.

    'If the searched string is "null", throw an exception.
    If (searched Is Nothing) Then Throw New ArgumentNullException("searched")

    'If the target string is "null", throw an exception.
    If (target Is Nothing) Then Throw New ArgumentNullException("target")

    'If the searched string doesn't contain the target string at all
    'then just return it - were done.
    Dim foundIndex As Integer = searched.IndexOf(target)
    If (foundIndex = -1) Then Return searched

    'Build a new string that replaces the target with the replacement.
    Return String.Concat(searched.Substring(0, foundIndex), replacement, _
        searched.Substring(foundIndex + target.Length, searched.Length - (foundIndex + target.Length)))
End Function

请注意,当您阅读下面的代码时,您甚至不必花一点时间来弄清楚它在做什么。它是可读的。当输入字符串包含 "A" 时,将第一个 "A" 替换为 "Bb"。

Dim input as string = "AAA"
While input.IndexOf("A") > -1
   input = input.ReplaceFirst(input,"A","Bb")
   'If you need to capture individual values of "input" as it changes
   'add them to a list.
End While

您可以优化或完全替换该功能。重要的是你的代码是可读的,有人可以知道它在做什么,并且 ReplaceFirst 函数是可测试的。

然后,假设您需要另一个函数,在替换目标字符串时为您提供输入字符串的所有 "versions":

Public Function GetIterativeReplacements(searched As String, target As String, replacement As String) As List(of string)
    Dim output As New List(Of String)
    While searched.IndexOf(target) > -1
        searched = ReplaceFirst(searched, target, replacement)
        output.Add(searched)
    End While
    Return output
End Function

如果你打电话

dim output as List(of string) = GetIterativeReplacments("AAAA","A","Bb")

它将return一个包含

的字符串列表
BbAAA, BbBbAA, BbBbBbA, BbBbBbBb

保持方法简短几乎总是好的。如果它们开始变得太长,只需将它们分成具有清晰名称的更小的方法。这样你就不会试图阅读、遵循和测试一个又大又长的函数。无论您是不是新程序员,这都很困难。诀窍在于无法创建我们理解的长而复杂的函数,因为我们编写了它们 - 它正在创建任何人都能理解的小而简单的函数。