how to get duplicate items from a list in vb.net

12,362

This has nothing to do with deferred execution, your algorithm is just wrong: Distinct does not return the unique items of the list, it just removes duplicates. Example: {"C1", "C12", "C10", "C1", "C6", "C22", "C1", "C6"}.Distinct() yields {"C1", "C12", "C10", "C6", "C22"} in your case. Thus, Set1.Except(DistinctItems) will always result in an empty list.


Here's an alternative solution to your problem. It selects all items whose count in the list is greater than one:

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

Usage example:

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"}

EDIT: Alternative solution using GroupBy (inspired by aquinas):

Dim duplicates = list.GroupBy(Function(x) x).Where(Function(x) x.Count > 1).Select(Function(x) x.Key)
Share:
12,362
tullynyguy
Author by

tullynyguy

Updated on August 01, 2022

Comments

  • tullynyguy
    tullynyguy over 1 year

    I have a List(of String). For example: {"C1", "C12", "C10", "C1", "C6", "C22", "C1", "C6"}. I am trying to write a function to give me a list of duplicates: {"C1", "C6"} in the list. Each duplicate will be listed only once. The function I wrote does give me anything back at all. I can't figure out why. Any help or alternative approaches are appreciated. FYI, I see a very similar question in C# but I don't know how to translate that syntax into VB.net since I am not up to speed on LINQ yet. It is here: 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