在 Visual Basic 中按键长度对 SortedDictionary 进行排序?
Sorting a SortedDictionary by key length in Visual Basic?
我正在编写一个脚本来匿名化文件中的参与者数据。
基本上,我有:
- 明文参与者数据文件夹(有时是 CSV,有时是 XML,有时是 TXT)
- 已知用户名和伴随的匿名 ID 的文件(例如 jsmith1 作为已知用户名,User123 作为匿名 ID)
我想用相应的匿名 ID 替换已知用户名的每个实例。
一般来说,我所用的方法工作得很好——它将用户名和匿名 ID 加载到字典中,并在文档文本中为每个 运行 一个一个地查找和替换。
然而,这个脚本也会去掉名字,当它遇到包含在其他名字中的名字时,运行会遇到一些困难。所以,例如,我有两对:
约翰,用户 123
约翰尼,User456
现在,当我 运行 查找和替换时,它可能首先遇到 John,结果它用 User123ny 替换了 Johnny,然后就不会触发 Johnny。
我能想到的最简单的解决方案就是 运行 从最长的密钥到最短的查找和替换。为此,我似乎需要一个 SortedDictionary。
但是,我似乎无法说服 Visual Basic 为此采用我的自定义比较器。你如何指定这个?我有的是:
Sub Main()
Dim nameDict As New SortedDictionary(Of String, String)(AddressOf SortKeyByLength)
End Sub
Public Function SortKeyByLength(key1 As String, key2 As String) As Integer
If key1.Length > key2.Length Then
Return 1
ElseIf key1.Length < key2.Length Then
Return -1
Else
Return 0
End If
End Function
(上面的完整细节是为了以防万一有人对如何解决这个问题有更好的想法。)
我认为它需要一个 class 来实现 IComparer 接口,所以您需要这样的东西:
Public Class ByLengthComparer
Implements IComparer(Of String)
Public Function Compare(key1 As String, key2 As String) As Integer Implements IComparer(Of String).Compare
If key1.Length > key2.Length Then
Return 1
ElseIf key1.Length < key2.Length Then
Return -1
Else
'[edit: in response to comments below]
'Return 0
Return key1.Compare(key2)
End If
End Function
End Class
然后,在您的 main 方法中,您可以这样调用它:
Dim nameDict As New SortedDictionary(Of String, String)(New ByLengthComparer())
您可能想要查看(或重新查看)SortedDictionary constructor, and how to make a class that implements IComparer 的文档。
我正在编写一个脚本来匿名化文件中的参与者数据。
基本上,我有:
- 明文参与者数据文件夹(有时是 CSV,有时是 XML,有时是 TXT)
- 已知用户名和伴随的匿名 ID 的文件(例如 jsmith1 作为已知用户名,User123 作为匿名 ID)
我想用相应的匿名 ID 替换已知用户名的每个实例。
一般来说,我所用的方法工作得很好——它将用户名和匿名 ID 加载到字典中,并在文档文本中为每个 运行 一个一个地查找和替换。
然而,这个脚本也会去掉名字,当它遇到包含在其他名字中的名字时,运行会遇到一些困难。所以,例如,我有两对:
约翰,用户 123 约翰尼,User456
现在,当我 运行 查找和替换时,它可能首先遇到 John,结果它用 User123ny 替换了 Johnny,然后就不会触发 Johnny。
我能想到的最简单的解决方案就是 运行 从最长的密钥到最短的查找和替换。为此,我似乎需要一个 SortedDictionary。
但是,我似乎无法说服 Visual Basic 为此采用我的自定义比较器。你如何指定这个?我有的是:
Sub Main()
Dim nameDict As New SortedDictionary(Of String, String)(AddressOf SortKeyByLength)
End Sub
Public Function SortKeyByLength(key1 As String, key2 As String) As Integer
If key1.Length > key2.Length Then
Return 1
ElseIf key1.Length < key2.Length Then
Return -1
Else
Return 0
End If
End Function
(上面的完整细节是为了以防万一有人对如何解决这个问题有更好的想法。)
我认为它需要一个 class 来实现 IComparer 接口,所以您需要这样的东西:
Public Class ByLengthComparer
Implements IComparer(Of String)
Public Function Compare(key1 As String, key2 As String) As Integer Implements IComparer(Of String).Compare
If key1.Length > key2.Length Then
Return 1
ElseIf key1.Length < key2.Length Then
Return -1
Else
'[edit: in response to comments below]
'Return 0
Return key1.Compare(key2)
End If
End Function
End Class
然后,在您的 main 方法中,您可以这样调用它:
Dim nameDict As New SortedDictionary(Of String, String)(New ByLengthComparer())
您可能想要查看(或重新查看)SortedDictionary constructor, and how to make a class that implements IComparer 的文档。