VB.net 将功能应用于列表中的项目

VB.net Apply function to items in a list

提问人:pball 提问时间:3/4/2021 更新时间:3/4/2021 访问量:355

问:

我有一个包含完整文件路径的字符串列表,我想对该列表中的每个路径应用一个函数,并在相同或新的列表中获取结果。

Dim Remove As New List(Of String)
Remove.Add("C:\_Vault\Designs\Jobs\Customer\Job23\Assemblies\045-0201.iam")
Remove.Add("C:\_Vault\Designs\Jobs\Customer\Job23\Parts\212-D017.ipt")
Remove.Add("C:\_Vault\Designs\Jobs\Customer\Job23\Parts\211-W01.iam")

Function FileName(spth As String) As String
    'Returns filename with extension from full path
    Return System.IO.Path.GetFileName(spth)
End Function

我想要的最终结果是列表Remove包含以下内容。我知道我可以使用循环来做到这一点,但我最近一直在学习 lambda 表达式,并且觉得应该有一个简单的解决方案。

{“045-0201.iam”, “212-D017.ipt”, “211-W01.iam”}

vb.net

评论

0赞 41686d6564 3/4/2021
Remove = Remove.Select(Function(s) FileName(s)).ToList().不过,您应该为变量和方法选择更好的名称。首先,应该命名为类似的东西(或者你可以摆脱它并直接使用)。FileNameGetFileNamePath.GetFileName()

答:

2赞 dbasnett 3/4/2021 #1

试试这个

    Dim Remove As New List(Of String)
    Remove.Add("C:\_Vault\Designs\Jobs\Customer\Job23\Assemblies\045-0201.iam")
    Remove.Add("C:\_Vault\Designs\Jobs\Customer\Job23\Parts\212-D017.ipt")
    Remove.Add("C:\_Vault\Designs\Jobs\Customer\Job23\Parts\211-W01.iam")

    Remove = Remove.Select(Function(s)
                               Return IO.Path.GetFileName(s)
                           End Function).ToList

评论

0赞 Jimi 3/4/2021
Remove = Remove.Select(Function(s) Path.GetFileName(s)).ToList(). 不需要。Return
0赞 dbasnett 3/4/2021
@Jimi - 我知道。它也可以写在一行上。试图变得明显。
2赞 jmcilhinney 3/4/2021 #2

打电话和现有很可能是好的,也是大多数人会做的事情。不过,值得注意的是,这不会修改现有集合,而是返回一个新集合。如果您只有一个对该列表的引用,那么这没什么大不了的,但是对现有列表的其他引用将不会看到更改,例如SelectToListList

Dim fileNames As New List(Of String) From {"C:\Folder\File1.ext",
                                           "C:\Folder\File2.ext",
                                           "C:\Folder\File3.ext"}
Dim temp = fileNames

fileNames = fileNames.Select(Function(s) Path.GetFileName(s)).ToList()

For Each fileName In fileNames
    Console.WriteLine(fileName)
Next

For Each fileName In temp
    Console.WriteLine(fileName)
Next

如果运行它,那么你会看到第一个循环只显示文件名,但第二个循环显示完整路径,因为它仍然引用原始列表。

如果这是一个问题,还有另一种方法可以在没有显式循环的情况下做到这一点:

Dim fileNames As New List(Of String) From {"C:\Folder\File1.ext",
                                           "C:\Folder\File2.ext",
                                           "C:\Folder\File3.ext"}
Dim temp = fileNames

Array.ForEach(Enumerable.Range(0, fileNames.Count).ToArray(),
              Sub(i) fileNames(i) = Path.GetFileName(fileNames(i)))

For Each fileName In fileNames
    Console.WriteLine(fileName)
Next

For Each fileName In temp
    Console.WriteLine(fileName)
Next

如果你运行它,那么你会看到两个循环只显示文件名,因为只有一个列表。

也就是说,如果第一个代码由于对列表的多次引用而造成问题,我只会使用循环。

0赞 Spyros P. 3/4/2021 #3

我知道你说过你想要一个循环以外的东西,但这里真的不需要任何花哨的东西。顺便说一句,写作听起来像个谜语。Remove.Add

    Sub Main()
    Dim Remove As New List(Of String)
    Remove.Add("C:\_Vault\Designs\Jobs\Customer\Job23\Assemblies\045-0201.iam")
    Remove.Add("C:\_Vault\Designs\Jobs\Customer\Job23\Parts\212-D017.ipt")
    Remove.Add("C:\_Vault\Designs\Jobs\Customer\Job23\Parts\211-W01.iam")
    Console.WriteLine("Before execution")
    For Each s As String In Remove
        Console.WriteLine(s)
    Next
    For i As Integer = 0 To Remove.Count - 1
        Remove(i) = MyFunction(Remove(i))
    Next
    Console.WriteLine("After execution")
    For Each s As String In Remove
        Console.WriteLine(s)
    Next

    Console.ReadLine()
End Sub

Private Function MyFunction(path As String) As String
    Return IO.Path.GetFileName(path)
End Function

这将输出:

enter image description here