XardasLord
XardasLord

Reputation: 1947

Check if List<Of List<T>> contains a List<T>

I have a List of my Objects with many Properties.

Dim Duplicates As New List(Of ElementObject)
Dim ListOfDuplicates As New List(Of List(Of ElementObject))

For Each Element As ElementObject In Duplicates
   Dim tmpList As List(Of ElementObject)

   'Im looking for list of elements with the same width and height in Duplicates list
   tmpList = Duplicates.FindAll(Function(x) x.Width = Element.Width And x.Height = Element.Height)
   tmpList = tmpLista.OrderBy(Function(x) x.Id).ToList()

   'Here is what I want: I want to look if tmpLista is already in ListOfDuplicates, but this code does not work
   If ListOfDuplicates.Contains(tmpList) Then
      Continue For
   End If

   ListOfDuplicates.Add(tmpList)
Next

How can I achieve this, to check if List of my another List of Objects contains that list already?

Upvotes: 0

Views: 97

Answers (2)

Scott Hannen
Scott Hannen

Reputation: 29292

You can use SequenceEqual to compare the contents of the list with two caveats:

  • The lists need to be sorted the same way
  • The objects in the lists have to be equatable. You can do this by overriding Equals or by implementing a function that checks for equality.

I'm more used to this in C# where the lambda expressions are easier to write and I can create an extension class without creating a separate module. This class provides the hash code calculation and comparisons to check two lists of elements for the same values. It calculates a set of hash codes for each list, sorts the hash codes, and then compares the sets of hash codes using SequenceEquals.

Public Class ElementListComparer
    Public Shared Function ListsAreEqual(list1 As IEnumerable(Of Element), list2 As IEnumerable(Of Element))
        If list1 Is Nothing OrElse list2 Is Nothing Then Return False
        If Object.ReferenceEquals(list1, list2) Then Return True
        return GetSortedHashCodes(list1).sequencequal(GetSortedHashCodes(list2))
    End Function

    Public Shared Function GetSortedHashCodes(elements As IEnumerable(Of Element))
        Return elements.Select(Function(el As Element) As Long
                                   Return CalculateHashCode(el)
                               End Function).OrderBy(Function(hashcode)
                                                         Return hashcode
                                                     End Function)
    End Function

    Public Shared Function CalculateHashCode(el As Element) As Long
        Return (el.Height * 397) ^ el.Width
    End Function
End Class

So you would call

ElementListComparer.ListsAreEqual(list1 as IEnumerable(of Element), list2 as IEnumerable(of Element))

Upvotes: 1

XardasLord
XardasLord

Reputation: 1947

This did the trick:

Dim Contain As Boolean = ListOfDuplicates.Any(Function(x) x.SequenceEqual(tmpList))

Upvotes: 0

Related Questions