【问题标题】:Best way to optimise For Loops and Do Until Loops [closed]优化 For 循环和直到循环的最佳方法 [关闭]
【发布时间】:2018-02-23 10:54:04
【问题描述】:

我有以下代码在 DataGridView 表中搜索文件夹目录,并将所需格式的所有文件放入一个列表中,它还收集它们最后修改日期的列表以供以后在应用程序中使用。

代码有效,但眼睛很痛。我想整理以下循环以提高效率 - 我的意思是我在创建文件名列表的 For 循环中有一个 For 循环,然后我有两个单独的 Do Until 循环从头到尾搜索列表选择需要调整的文件名。

我很想学习一种更好的方法来实现相同的结果,因为我对编码效率的了解非常初级。基本上,这可以在一两个循环中完成吗,因为循环两次列表的想法似乎效率低下?

Public Class
    Private Sub btnDirectory_Click(sender As Object, e As EventArgs) Handles btnDirectory.Click

    Dim FileNames As New List(Of String)
    Dim FileDates As New List(Of Date)

    Dim DocNo As String
    Dim rowCheck As String
    Dim ProjectNo As String = "1111"
    Dim FileNameCheck As String
    Dim str As String

    Dim k As Integer = 0 
    Dim i As Integer
    Dim j As Integer

    Dim CorrectType As Boolean = False

    'The first loop grabs all files of the wanted format from a datagridview table containing all directories to be checked

    For Each rw In Background.Table1.Rows

        rowCheck = Background.Table1(0, k).Value
        If Not String.IsNullOrEmpty(rowCheck) Then

        For Each file As String In My.Computer.FileSystem.GetFiles(Background.Table1(0, k).Value)
            CorrectType = False
            FileNameCheck = IO.Path.GetFileNameWithoutExtension(file)
            If FileNameCheck.Contains(ProjectNo) AndAlso FileNameCheck.Contains("-") AndAlso Not String.IsNullOrEmpty(FileNameCheck) AndAlso FileNameCheck.Contains(" ") Then
                DocNo = FileNameCheck.Substring(0, FileNameCheck.IndexOf(" "))
                If FileNameCheck.Substring(0, FileNameCheck.IndexOf("-")) = ProjectNo AndAlso CountLetters(DocNo) = 3 Then
                    CorrectType = True                                   
                End If
            End If
            If CorrectType = True Then
                FileNames.Add(FileNameCheck)
                FileDates.Add(IO.File.GetLastWriteTime(file))
            End If

        Next
        End If

        k += 1

    Next

    'The next loop tidies up the file formats that contain a "-00-" in their names

     j = FileNames.Count
     i = 0
     Do
         str = FileNames(i)
         If str.Contains("-00-") Then                           
             FileNames(i) = RemoveChar(str, "-00-") ' RemoveChar is a function that replaces "-00-" with a "-"
         End If
         i += 1
     Loop Until i = j

     i = 0
     j = FileNames.Count


     'Finally, this loop checks that no two files have the exact same name, and gets rid of one of them if that is the case

     Do

         Dim st1 As String = FileNames(j - 1)
         Dim st2 As String = FileNames(j - 2)

         If st1 = st2 Then          
             FileNames.RemoveAt(j - 1)
             FileDates.RemoveAt(j - 1)
         End If
         j -=  1
     Loop Until j = 1


     End Sub


End Class

【问题讨论】:

  • a) 为什么您认为“速度”可以提高?这是 I/O 绑定的。
  • b) 每当您看到需要执行 k += 1 的 ForEach 循环时,您都应该使用 For 循环。
  • c) CorrectType 变量仅用于添加一个额外的 IF/EndIf,您可以不这样做
  • 但是你真的应该在 CodeReview 网站上发布这个。
  • 谢谢 Henk Holterman,我现在就把这个问题贴在那里

标签: vb.net loops for-loop do-loops


【解决方案1】:

代码确实很难看。

For Each rw 循环不使用rw。您可以将其替换为循环,例如:

For k = 1 to Background.Table1.Rows.Count
    ' Do things here
Next k

您分配了rowCheck 并使用了一次,但您错过了在For Each file 行中重复使用它的机会。

如果您有CorrectType = True,您可以轻松地放置相应的代码。

        If FileNameCheck.Substring(0, FileNameCheck.IndexOf("-")) = ProjectNo AndAlso CountLetters(DocNo) = 3 Then
            CorrectType = True                                   
        End If
    End If
    If CorrectType = True Then
        FileNames.Add(FileNameCheck)
        FileDates.Add(IO.File.GetLastWriteTime(file))
    End If

变成:

        If FileNameCheck.Substring(0, FileNameCheck.IndexOf("-")) = ProjectNo AndAlso CountLetters(DocNo) = 3 Then
            FileNames.Add(FileNameCheck)
            FileDates.Add(IO.File.GetLastWriteTime(file))
        End If

我必须承认,接下来的两个循环让我的眼睛流血了(比喻而不是字面意思)。

 j = FileNames.Count
 i = 0
 Do
     str = FileNames(i)
     If str.Contains("-00-") Then                           
         FileNames(i) = RemoveChar(str, "-00-") ' RemoveChar is a function that replaces "-00-" with a "-"
     End If
     i += 1
 Loop Until i = j

变成

 for i = 1 to FileNames.Count
     str = FileNames(i)
     If str.Contains("-00-") Then                           
         FileNames(i) = RemoveChar(str, "-00-") ' RemoveChar is a function that replaces "-00-" with a "-"
     End If
 Next I

    i = 0
    j = FileNames.Count
 'Finally, this loop checks that no two files have the exact same name, and gets rid of one of them if that is the case

 Do

     Dim st1 As String = FileNames(j - 1)
     Dim st2 As String = FileNames(j - 2)

     If st1 = st2 Then          
         FileNames.RemoveAt(j - 1)
         FileDates.RemoveAt(j - 1)
     End If
     j -=  1
 Loop Until j = 1

变成

 'Finally, this loop checks that no two files have the exact same name, and gets rid of one of them if that is the case

 For j = FileNames.Count - 1 to 1 Step -1 ' Check my counting here - stop at 1, 2 or 0?

     Dim st1 As String = FileNames(j)
     Dim st2 As String = FileNames(j - 1)

     If st1 = st2 Then          
         FileNames.RemoveAt(j)
         FileDates.RemoveAt(j)
     End If
 Next j

【讨论】:

  • 谢谢你,我喜欢你的态度 - 非常感谢你的帮助。我很高兴你的眼睛只是象征性地流血。我不得不将第一个循环调整为“For k = 1 To Background.Table1.Rows.Count - 1”,将第二个循环调整为“For i = 0 To FileNames.Count - 1”,让我知道是否不应该是这样的
  • Jay,这个调整很好 - 很好的调试,看起来你正在使用基于 0 的数组。
猜你喜欢
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多