0

How can I create a method which will receive 2 arrays and return them without duplicates?

Currently I have a very low background in VB.NET

Here is my code

Imports System

Module Module1

    Public Class MergeNames
        Public Shared Function UniqueNames(names1() As String, names2() As String) As String()
            Throw New NotImplementedException()
        End Function
    End Class

    Public Sub Main()
        Dim names1() As String = {"Ava", "Emma", "Olivia"}
        Dim names2() As String = {"Olivia", "Sophia", "Emma"}
        Console.WriteLine(string.Join(", ", MergeNames.UniqueNames(names1, names2))) ' should print Ava, Emma, Olivia, Sophia
    End Sub

End Module

I Expect to get only Ava and Sophia in the UniqueNames method

0

5 Answers 5

3

These are simple operations, and there's no reason to make them specific to Strings. You can use the generic function below to get the distinct set of items of any two sets of any single type.

Module Module1

    ' Ava, Emma, Olivia, Sophia
    Public Function GetDistinctItems(Of T)(items1 As IEnumerable(Of T), items2 As IEnumerable(Of T)) As IEnumerable(Of T)
        Return items1.Concat(items2).Distinct()
    End Function

    ' Emma, Olivia
    Public Function GetDuplicateItems(Of T)(items1 As IEnumerable(Of T), items2 As IEnumerable(Of T)) As IEnumerable(Of T)
        Return items1.Join(items2, Function(i) i, Function(i) i, Function(i, j) i)
    End Function

    ' Ava, Sophia
    Public Function GetUniqueItems1(Of T)(items1 As IEnumerable(Of T), items2 As IEnumerable(Of T)) As IEnumerable(Of T)
        Return items1.Concat(items2).Except(GetDuplicateItems(items1, items2))
    End Function

    ' Ava, Sophia
    Public Function GetUniqueItems2(Of T)(items1 As IEnumerable(Of T), items2 As IEnumerable(Of T)) As IEnumerable(Of T)
        Return items1.Concat(items2).GroupBy(Function(i) i).Where(Function(i) i.Count() = 1).Select(Function(i) i.Key)
    End Function

    Public Sub Main()
        Dim names1 = {"Ava", "Emma", "Olivia"}
        Dim names2 = {"Olivia", "Sophia", "Emma"}
        Console.WriteLine(String.Join(", ", GetDistinctItems(names1, names2)))
        ' or simply do it inline
        Console.WriteLine(String.Join(", ", names1.Concat(names2).Distinct()))

        Console.WriteLine(String.Join(", ", GetDuplicateItems(names1, names2)))
        Console.WriteLine(String.Join(", ", GetUniqueItems1(names1, names2)))
        Console.WriteLine(String.Join(", ", GetUniqueItems2(names1, names2)))
    End Sub

End Module

The LINQ operation for distinct is so simple that it also fits nicely inline in your Console.Writeline.

Sign up to request clarification or add additional context in comments.

1 Comment

Indeed, that solves the answer I wrote in the questions thanks for the examples, now I just got to know LINQ yesterday
1

Your answer contradicts the expectation in your question, which is :

I Expect to get only Ava and Sophia in the UniqueNames method

The shortest way that I can think of to get whichever you need is by using the IEnumerable built-in functions of as follows :

Sub Main
    Dim names1 = {"Ava", "Emma", "Olivia"}
    Dim names2 = {"Olivia", "Sophia", "Emma"}

    Console.WriteLine(String.Join(", ", GetDistinctItems(names1, names2))) ' Returns "Ava, Emma, Olivia, Sophia"
    Console.WriteLine(String.Join(", ", GetUniqueItems(names1, names2))) ' Returns "Ava, Sophia"
End Sub

Public Function GetDistinctItems(Of T)(items1 As IEnumerable(Of T), items2 As IEnumerable(Of T)) As IEnumerable(Of T)
    Return items1.Union(items2)
End Function

Public Function GetUniqueItems(Of T)(items1 As IEnumerable(Of T), items2 As IEnumerable(Of T)) As IEnumerable(Of T)
    Return items1.Union(items2).Except(items1.Intersect(items2))
End Function

Comments

0

Please Try This:

Private Function CombineArray(ByVal Array1() As String, ByVal Array2() As String) As String()
    Dim myArray(Array1.Length + Array2.Length - 1) As String
    Array1.CopyTo(myArray, 0)
    Array2.CopyTo(myArray, Array1.Length)
    Return myArray
End Function

Private Function GetJustUnique(ByVal ArrayToCheck() As String) As String()
    Dim UniqueOnly() = ArrayToCheck.Where(Function(x) ArrayToCheck.Where(Function(y) x = y).Count() = 1).Distinct().ToArray
    Return UniqueOnly
End Function

Private Sub btnGetUnique_Click(sender As Object, e As EventArgs) Handles btnGetUnique.Click
    Dim names1() As String = {"Ava", "Emma", "Olivia"}
    Dim names2() As String = {"Olivia", "Sophia", "Emma"}
    Dim names3() As String = GetJustUnique(CombineArray(names1, names2))
End Sub

or the shortest:

Private Sub btnGetUnique_Click(sender As Object, e As EventArgs) Handles btnGetUnique.Click
    Dim names1() As String = {"Ava", "Emma", "Olivia"}
    Dim names2() As String = {"Olivia", "Sophia", "Emma"}
    'if you will use the result
    Dim UniqueOnly() = names1.Concat(names2).Where(Function(x) names1.Concat(names2).Where(Function(y) x = y).Count() = 1).Distinct().ToArray
    'if you just will write to console
    Console.WriteLine(String.Join(", ", names1.Concat(names2).Where(Function(x) names1.Concat(names2).Where(Function(y) x = y).Count() = 1).Distinct().ToArray)) 
End Sub

And more additional info for linq without concat:

    'Dim ItemNames2InNames1 = From a In names2 Where (names1.Contains(a))
    'Return {Olivia, Emma}

    'Dim ItemNames2NotInNames1 = From a In names2 Where (Not names1.Contains(a))
    'Return {Sophia}

    'Dim ItemNames1InNames2 = From a In names1 Where (names2.Contains(a))
    'Return {Olivia, Emma}

    'Dim ItemNames1NotInNames2 = From a In names1 Where (Not names2.Contains(a))
    'Return {Ava}

Comments

0
Imports System
Imports System.Collections.Generic
Imports System.Linq

Public Module MergeNames
    Public Shared Function UniqueNames(names1 As IEnumerable(Of String), names2 As IEnumerable(Of String)) As IEnumerable(Of String)
        Return names1.Except(names2).Concat(names2.Except(names1))
    End Function
End Module

Module Module1

    Public Sub Main()
        'Can still use arrays here, even though the method now asks for IEnumerable(Of String)
        Dim names1() As String = {"Ava", "Emma", "Olivia"}
        Dim names2() As String = {"Olivia", "Sophia", "Emma"}
        Console.WriteLine(string.Join(", ", MergeNames.UniqueNames(names1, names2))) ' should print Ava, Emma, Olivia, Sophia
    End Sub
End Module

Comments

-1
Imports System
Imports System.Collections

Module Module1

Public Class MergeNames
    Public Shared Function UniqueNames(names1() As String, names2() As String) As String()
        Dim result as New ArrayList
        Dim cont as Integer = 0

        'Dim aux As New List(Of String)

        Dim aux As Hashtable = New Hashtable

        For Each n1 as String in names1
            If Not(aux.Contains(n1)) Then
                aux.Add(n1, "")
                result.add(n1)
            End If
        Next

        For Each n2 as String in names2
            If Not(aux.Contains(n2)) Then
                aux.Add(n2, "")   
                result.add(n2)
            End If
        Next

        Dim res() As String = result.ToArray(GetType(String))

        Return res
    End Function
End Class

Public Sub Main()
    Dim names1() As String = {"Ava", "Emma", "Olivia"}
    Dim names2() As String = {"Olivia", "Sophia", "Emma"}
    Console.WriteLine(string.Join(", ", MergeNames.UniqueNames(names1, names2))) ' should print Ava, Emma, Olivia, Sophia
End Sub
End Module

Got it working on my own, thanks stack!

4 Comments

Gah, ArrayList is not your friend.
This was testing code to test my knowledge, it's really sad I could not actually figure out my question correctly and instead got several different answers that answered the wrong questions I did on here, however after a couple of videos in yt I got to understand the syntax of vbnet and noticed I was miss leading the topic of the real resolution of this problem, altho my code solves the real questions I got to know several different ways to solve my original questions, tho why ArrayList is not my friend, cant understand this
ArrayList exists only for backwards compatibility with older code, and should not be used anymore for new development. In it's place, use a generic List(Of T). This improves performance by avoiding boxing and casting, and improves safety by giving you better type checking at build time, and it easier to write code for because you get better intellisense in the IDE and don't need to manually write out casts.
HashTable is the same way. Both ArrayList and HashTable were important in .Net 1.0/1.1, before there were generics, and for some time after while older code was updated and maintained. And they remain part of the framework for use in places where types are less strict like PowerShell, but have been largely obsolete since .Net 2.0 came out in 2005... nearly 15 years now!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.