【问题标题】:Check whether two lists have at least one common item检查两个列表是否至少有一个共同项
【发布时间】:2013-07-23 13:44:59
【问题描述】:

如果有两个列表:

Dim list1 As New List(Of Integer)
list1.AddRange({1, 2, 3})

Dim list2 As New List(Of Integer)
list2.AddRange({1, 4, 5})

在 VB.NET 中,就性能而言,检测它们是否有一个或多个公共项的最佳方法是什么?这应该是通用的。

【问题讨论】:

    标签: vb.net performance list generics comparison


    【解决方案1】:
    <System.Runtime.CompilerServices.Extension()> _
    Function ContainsAny(Of T)(col1 As IEnumerable(Of T), col2 As IEnumerable(Of T)) As Boolean
        ' performance checks
        If col1 Is Nothing OrElse col2 Is Nothing Then Return False
        If col1 Is col2 Then Return True
        ' compare items, using the smallest collection
        If col1.Count < col2.Count Then
            Dim hs1 As New HashSet(Of T)(col1)
            For Each v In col2
                If hs1.Contains(v) Then Return True
            Next
        Else
            Dim hs2 As New HashSet(Of T)(col2)
            For Each v In col1
                If hs2.Contains(v) Then Return True
            Next
        End If
        Return False
    End Function
    

    代码示例:

    Dim list1 As New List(Of Integer)
    list1.AddRange({1, 2, 3})
    
    Dim list2 As New List(Of Integer)
    list2.AddRange({1, 4, 5})
    
    Dim anyMatch As Boolean = list1.ContainsAny(list2)
    

    【讨论】:

    • 随着 Contains 的工作原理,IIRC 它将遍历所有元素以找到您需要的元素,这非常慢。我认为更好的方法是迭代一次并将值放入 Hashset 或 Dictionary 中(取决于所使用的 .NET 版本),然后分别使用 ContainsContainsKey
    【解决方案2】:

    在 C# 中(但在 VB 中也可能有效)

    list1.Intersect(list2).Any()
    

    【讨论】:

    • 性能怎么样,这不是在检查匹配项之前做一个完整的相交吗?
    • 在性能方面,这应该不是问题,因为 LINQ 是懒惰的。所以只要有一个元素相交,它就会返回(前提是 Intersect 是惰性的,我认为是)
    • 不,我错了,list1 在产生任何结果之前会被完全迭代
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 1970-01-01
    相关资源
    最近更新 更多