VB.NET如何提取Records类中TNumber与TUnit的唯一字符串组合?
提取Records中TNumber与TUnit的唯一组合存入StringsUnique
我有两个类:一个存储所有记录的Records类,一个存储唯一字符串组合的StringsUnique类。
Records类代码
Public Class Records Public Property ID As String Public Property TNumber As String Public Property TUnit As String Public Property SiteName As String Public Property FName As String Public Property LName As String Public Property MName As String Public Property Suffix As String Public Property Address1 As String Public Property Address2 As String Public Property City As String Public Property State As String Public Property PostalCode As String Public Property Email As String Public Property HomePhone As String Public Property MobilePhone As String Public Property Gender As String Public Property HireDate As String Public Property BirthDate As String End Class
StringsUnique类代码
Private Class StringsUnique Public Property S1 As String Public Property S2 As String Public Sub New(s1 As String, s2 As String) Me.S1 = s1 Me.S2 = s2 End Sub End Class
需求
需要从Records集合中提取TNumber与TUnit的唯一组合,存入StringsUnique集合。比如输入组合:
"02547", "03" "02547", "05" "02547", "03"
期望得到唯一结果:"02547, 03"和"02547, 05"。
尝试的错误代码
我写了一段循环代码,但返回了所有组合,无法实现去重:
Dim InsertCheck As Boolean = False For I = 0 To Records.Count - 1 If StringsUnique.Count <> 0 Then For U = 0 To StringsUnique.Count - 1 If (StringsUnique.Item(U).S1 <> Records(I).TNumber.ToString And StringsUnique.Item(U).S2 <> Records(I).TUnit) Or (StringsUnique.Item(U).S1 = Records(I).TNumber.ToString And StringsUnique.Item(U).S2 <> Records(I).TUnit) Or (StringsUnique.Item(U).S1 <> Records(I).TNumber.ToString And StringsUnique.Item(U).S2 = Records(I).TUnit) Then InsertCheck = True End If Next Else StringsUnique.Add(New StringsUnique(Records(I).TNumber.ToString, Records(I).TUnit.ToString)) End If If InsertCheck = True Then StringsUnique.Add(New StringsUnique(Records(I).TNumber.ToString, Recprds(I).TUnit.ToString)) End If InsertCheck = False Next
请问该如何修改以实现提取唯一字符串组合的需求?
解决方案
方法一:使用LINQ(简洁高效)
VB.NET的LINQ可以快速实现分组去重,代码更简洁易维护:
方式1:直接分组转换
无需修改StringsUnique类,通过匿名类型分组(匿名类型默认按属性值比较相等),再转换为目标类:
' 假设recordsList是你的Records集合实例 Dim uniqueCombos = recordsList.GroupBy(Function(r) New With {Key r.TNumber, Key r.TUnit}) _ .Select(Function(g) New StringsUnique(g.Key.TNumber, g.Key.TUnit)) _ .ToList()
方式2:为StringsUnique实现相等比较(推荐复用)
如果后续需要多次比较StringsUnique实例,让类实现IEquatable(Of StringsUnique),这样可以直接用Distinct()方法:
Private Class StringsUnique Implements IEquatable(Of StringsUnique) Public Property S1 As String Public Property S2 As String Public Sub New(s1 As String, s2 As String) Me.S1 = s1 Me.S2 = s2 End Sub Public Function Equals(other As StringsUnique) As Boolean Implements IEquatable(Of StringsUnique).Equals If other Is Nothing Then Return False Return Me.S1 = other.S1 AndAlso Me.S2 = other.S2 End Function Public Overrides Function Equals(obj As Object) As Boolean Return Equals(TryCast(obj, StringsUnique)) End Function Public Overrides Function GetHashCode() As Integer Return HashCode.Combine(S1, S2) End Function End Class
之后去重代码如下:
Dim uniqueCombos = recordsList.Select(Function(r) New StringsUnique(r.TNumber, r.TUnit)) _ .Distinct() _ .ToList()
方法二:修正循环代码
如果不想用LINQ,修改原循环逻辑,核心是检查当前组合是否已存在,不存在才添加:
简化版(用For Each和Any方法)
Dim StringsUnique As New List(Of StringsUnique)() Dim recordsList As List(Of Records) = ' 你的Records集合实例 For Each record In recordsList ' 检查当前组合是否已存在 Dim exists = StringsUnique.Any(Function(su) su.S1 = record.TNumber AndAlso su.S2 = record.TUnit) If Not exists Then StringsUnique.Add(New StringsUnique(record.TNumber, record.TUnit)) End If Next
索引循环版(修正原代码逻辑)
Dim StringsUnique As New List(Of StringsUnique)() Dim recordsList As List(Of Records) = ' 你的Records集合实例 For I = 0 To recordsList.Count - 1 Dim currentTNumber = recordsList(I).TNumber Dim currentTUnit = recordsList(I).TUnit Dim isExists = False ' 遍历现有组合,检查是否匹配 For U = 0 To StringsUnique.Count - 1 If StringsUnique(U).S1 = currentTNumber And StringsUnique(U).S2 = currentTUnit Then isExists = True Exit For ' 找到匹配项后直接跳出循环,无需继续检查 End If Next ' 不存在则添加 If Not isExists Then StringsUnique.Add(New StringsUnique(currentTNumber, currentTUnit)) End If Next
原代码逻辑错误在于:只要有任意一个现有组合不匹配,就标记InsertCheck=True并添加,导致重复插入。正确逻辑是找到匹配项则跳过,找不到才添加。
内容的提问来源于stack exchange,提问作者user24900496
相关产品推荐
相关产品推荐

