【问题标题】:vb .net How can I remove a filename from the collection returned by GetFilesvb .net 如何从 GetFiles 返回的集合中删除文件名
【发布时间】:2017-09-28 13:48:38
【问题描述】:

My.Computer.FileSystem.GetFiles 返回“返回表示目录中文件名的字符串的只读集合。”

我想在集合中随机选择一个文件,处理它,从列表中删除它,然后重复直到处理完所有文件。

我只能想到将集合从 GetFiles 复制到可变集合。 但 GetFiles 最终可能会返回数百万个文件名。

【问题讨论】:

    标签: c# asp.net .net vb.net


    【解决方案1】:

    只需在函数调用的末尾添加一个.ToList()。

    我还建议对列表进行洗牌并迭代洗牌的项目,而不是从列表中间随机选择您的项目。这比从集合中删除项目更容易。

    【讨论】:

    • 甜蜜!好想法。对于这种情况,您推荐什么 shuffle 方法?
    • 哇,我不确定是否复杂的洗牌比简单地从列表中删除每个文件更有效,如果链表可能会非常快。
    • 但List<T> 不是链接列表。每次从列表中删除一个项目(调用List.Remove() 或List.RemoveAt(),.Net 分配一个正确大小的新缓冲区并将所有元素复制到新缓冲区。对于洗牌,是的,你需要编写你自己的 shuffle —— 框架应该已经包含了这个开箱即用的内容:(——但是只需谷歌搜索 Fisher-Yates ,你就会发现很多示例代码展示了如何做到这一点而不会大惊小怪。
    【解决方案2】:

    使用这个泛型函数根据Fisher-Yates Shuffle进行洗牌

    Shared r = New Random() ' must not create new Random each time
    
    Public Shared Function Shuffle(Of T)(source As IEnumerable(Of T)) As IEnumerable(Of T)
        Dim n = source.Count()
        Dim a(n - 1) As T
        For i = 0 To n - 1
            Dim j = r.Next(0, i + 1)
            If i <> j Then
                a(i) = a(j)
            End If
            a(j) = source(i)
        Next
        Return a
    End Function
    

    然后您可以遍历已洗牌的列表。迭代时无需删除项目。

    Dim source = My.Computer.FileSystem.GetFiles("C:/")
    Dim result = Shuffle(source)
    For Each r In result
        ' process file
    Next
    

    【讨论】:

      【解决方案3】:

      my_mutable_list = My.Computer.FileSystem.GetFiles(my_dir_path).ToList()

      然后,根据需要从 my_mutable_list 中删除每个文件。

      【讨论】:

        猜你喜欢
        • 2019-02-17
        • 1970-01-01
        • 2010-10-13
        • 1970-01-01
        • 2011-02-11
        • 1970-01-01
        • 2017-02-21
        • 2020-01-03
        • 1970-01-01
        相关资源
        最近更新 更多