You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 10:23:19