如何从vb.net中的列表中获取重复项

时间:2012-05-31 14:35:05

标签: .net vb.net linq

我有一个List(of String)。例如:{“C1”,“C12”,“C10”,“C1”,“C6”,“C22”,“C1”,“C6”}。我正在尝试编写一个函数来给我一个重复列表:列表中的{“C1”,“C6”}。每个副本只列出一次。我写的功能确实给了我任何回报。我无法弄清楚为什么。任何帮助或替代方法都表示赞赏。仅供参考,我在C#中看到一个非常相似的问题,但我不知道如何将该语法转换为VB.net,因为我还没有达到LINQ的速度。它在这里:How to get duplicate items from a list using LINQ?

    ''' <summary>
    ''' Given a List(Of String), returns a list of items that are duplicated in the list.
    ''' Each duplicate returned is unique.
    ''' </summary>
    ''' <param name="Set1"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GetDuplicateItems(ByVal Set1 As List(Of String)) As List(Of String)
        Dim DistinctItems As IEnumerable(Of String)
        'Dim DistinctResults As New List(Of String)
        Dim DuplicateItems As IEnumerable(Of String)
        Dim ItemsToReturn As New List(Of String)

        'Get a set of unique items in the list
        DistinctItems = Set1.Select(Function(x) x).Distinct()
        'Do I need to enumerate the result in order to force the thing to execute?
        'See remarks section of http://msdn.microsoft.com/en-us/library/bb300779.aspx
        'For Each Item As String In DistinctItems
        '    DistinctResults.Add(Item)
        'Next
        'Do a set subtraction (Set1 - UniqueItems)
        DuplicateItems = Set1.Except(DistinctItems)

        For Each Item As String In DuplicateItems
            ItemsToReturn.Add(Item)
        Next

        Return ItemsToReturn
    End Function

1 个答案:

答案 0 :(得分:8)

这与延迟执行无关,你的算法是错误的:Distinct不返回列表的唯一项,它只是删除了重复项。示例:{"C1", "C12", "C10", "C1", "C6", "C22", "C1", "C6"}.Distinct()在您的情况下产生{"C1", "C12", "C10", "C6", "C22"}。因此,Set1.Except(DistinctItems)将始终生成一个空列表。


这是您的问题的替代解决方案。它选择列表中计数大于1的所有项目:

Dim duplicates = list.Where(Function(x) list.Where(Function(y) x = y).Count() > 1).Distinct()

用法示例:

Dim list As New List(Of String) From {"a", "a", "b", "c", "c"}
Dim duplicates = list.Where(Function(x) list.Where(Function(y) x = y).Count() > 1).Distinct()
' duplicates now contains {"a", "c"}

编辑:使用GroupBy的替代解决方案(受aquinas启发):

Dim duplicates = list.GroupBy(Function(x) x).Where(Function(x) x.Count > 1).Select(Function(x) x.Key)