Creating an IEqualityComparer for Arrays and Distinct

Nathan Sokalski 4,116 Reputation points
2020-05-05T23:32:28.79+00:00

I have an array of arrays of integer (a jagged array, Integer()()) from which I want to remove duplicates. For example, if I have the following:

Dim testvalues As Integer()() = {
    ({2, 4, 3, 1, 5}),
    ({1, 3, 5, 2, 4}),
    ({5, 4, 3, 2, 1}),
    ({1, 2, 3, 4, 5}),
    ({2, 4, 1, 3, 5}),
    ({1, 2, 3, 4, 5}),
    ({5, 4, 3, 2, 1}),
    ({1, 2, 3, 4, 5})}

I want to use the Distinct() method to get the following:

Dim distincttestvalues As Integer()() = {
    ({2, 4, 3, 1, 5}),
    ({1, 3, 5, 2, 4}),
    ({5, 4, 3, 2, 1}),
    ({1, 2, 3, 4, 5}),
    ({2, 4, 1, 3, 5})}

I have been unable to find an existing way to do this, so I figured the best solution would be to create an IEqualityComparer (which I have never done before) that uses the SequenceEqual method. Is this the best way to remove duplicate arrays, or do I need to resort to manually finding them using loops & if statements? Thanks.

Not Monitored
Not Monitored
Tag not monitored by Microsoft.
35,782 questions
0 comments No comments
{count} votes

Accepted answer
  1. Nathan Sokalski 4,116 Reputation points
    2020-05-06T17:16:04.13+00:00

    I think I managed to find an answer that I like, I created the following class by inheriting from EqualityComparer:

    Public Class ArrayComparer(Of T) : Inherits EqualityComparer(Of T())
        Public Overrides Function Equals(x As T(), y As T()) As Boolean
            Return x.SequenceEqual(y)
        End Function
        Public Overrides Function GetHashCode(obj As T()) As Integer
            Return obj.Length.GetHashCode()
        End Function
    End Class
    

    And then I just used .Distinct(New ArrayComparer(Of Integer)()) in my code. I knew there had to be a simple way to do it, I think this was just one of those first time things (and I have always been somewhat confused by the GetHashCode method). But this seems to work well enough (at least for my scenario).

    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Fay Wang - MSFT 5,191 Reputation points
    2020-05-06T03:17:00.32+00:00

    Hello,

    Welcome to Microsoft Q&A!

    Q&A currently is under a public preview, All the supported topics are on the right top. Your issue is not supported right now, you can ask it in this forum.

    Thanks.

    0 comments No comments

  2. Peter Fleischer (former MVP) 19,231 Reputation points
    2020-05-06T05:55:54.297+00:00

    Hi, you can write your own Extension like in this console demo:

    Imports System.Runtime.CompilerServices
    
    Module Module48
    
      Sub Main()
        Try
          Call (New Demo).Execute()
        Catch ex As Exception
          Console.WriteLine(ex.ToString)
        End Try
        Console.WriteLine("Continue enter key")
        Console.ReadKey()
      End Sub
    
      Friend Class Demo
        Friend Sub Execute()
          Dim testvalues As Integer()() = {
            ({2, 4, 3, 1, 5}),
            ({1, 3, 5, 2, 4}),
            ({5, 4, 3, 2, 1}),
            ({1, 2, 3, 4, 5}),
            ({2, 4, 1, 3, 5}),
            ({1, 2, 3, 4, 5}),
            ({5, 4, 3, 2, 1}),
            ({1, 2, 3, 4, 5})}
    
          Dim distincttestvalues = testvalues.DistinctTest
    
          For i = 0 To distincttestvalues.GetUpperBound(0)
            For k = 0 To distincttestvalues(i).GetUpperBound(0)
              Console.Write($" {distincttestvalues(i)(k)}")
            Next
            Console.WriteLine()
          Next
    
        End Sub
      End Class
    
    End Module
    
    Public Module ArrayExtensions
    
      <Extension()>
      Public Function DistinctTest(inp As Integer()()) As Integer()()
        Dim cacheList As New List(Of Integer())
        For i = 0 To inp.GetUpperBound(0)
          Dim sw As Boolean = False
          For k = 0 To cacheList.Count - 1
            If inp(i).SequenceEqual(cacheList(k)) Then
              sw = True
              Exit For
            End If
          Next
          If Not sw Then cacheList.Add(inp(i))
        Next
        Dim out(cacheList.Count - 1)() As Integer
        For i = 0 To out.GetUpperBound(0)
          out(i) = cacheList(i)
        Next
        Return out
      End Function
    
    End Module
    
    0 comments No comments