Results 1 to 15 of 15

Thread: Prevent Duplicates in Array

  1. #1

    Thread Starter
    New Member
    Join Date
    May 2022
    Posts
    2

    Prevent Duplicates in Array

    How do I prevent duplicate values in an Array?

    The elements of my Array are added by generating random numbers when I click a button on my form but shouldn't have the same value more than once.

    I have seen code online for removing duplicates but that changes the size of the Array and I need it to remain the same size as it is used to populate 6 labels on my form.

    This is the code I am using to fill my array.

    Code:
    Dim Lotto(6) As Integer
    Dim RndLotto As New Random
    Dim X As Integer
    
    For X = 1 To UBound(Lotto)
          Lotto(X) = RndLotto.Next(1, 59)
    Next

  2. #2
    Frenzied Member
    Join Date
    Nov 2017
    Posts
    1,970

    Re: Prevent Duplicates in Array

    Assuming this is homework, the expected solution likely is to:

    - Generate the random number and store it in a temporary variable
    - Pass that random number to a function that checks the array to see if that number is already in the array
    -- If it is already in the array, generate a new random number, store it in that temporary variable, and repeat the previous step
    -- If it is not already in the array, then assign it to the lotto array

    Good luck.

  3. #3
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    24,813

    Re: Prevent Duplicates in Array

    There were a couple of points i noticed. Check the comments...

    Code:
    Dim Lotto(5) As Integer ' if you want a 6 element array
    Dim RndLotto As New Random
    
    For x As Integer = 0 To Lotto.GetUpperBound(0) ' LBound to ubound
        Dim n As Integer = RndLotto.Next(1, 60) ' random number 1 to 59
        If Not Lotto.Contains(n) Then ' ensure unique numbers
            Lotto(x) = n
        Else
            x -= 1
        End If
    Next

  4. #4

    Thread Starter
    New Member
    Join Date
    May 2022
    Posts
    2

    Thumbs up Re: Prevent Duplicates in Array

    Quote Originally Posted by .paul. View Post
    There were a couple of points i noticed. Check the comments...

    Code:
    Dim Lotto(5) As Integer ' if you want a 6 element array
    Dim RndLotto As New Random
    
    For x As Integer = 0 To Lotto.GetUpperBound(0) ' LBound to ubound
        Dim n As Integer = RndLotto.Next(1, 60) ' random number 1 to 59
        If Not Lotto.Contains(n) Then ' ensure unique numbers
            Lotto(x) = n
        Else
            x -= 1
        End If
    Next
    Thanks. That works perfectly.

  5. #5
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    108,501

    Re: Prevent Duplicates in Array

    How about you don't allow duplicates in the first place? Then there's no need to prevent them being placed in the array. How does a real lottery draw work? It puts all the possible values into a container and then removes items at random from that container. Why can't you do that?

    https://www.vbforums.com/showthread....ns-from-a-List

    Alternatively, you could treat it like dealing cards, i.e. randomise the whole list and then remove the first item repeatedly.

    https://www.vbforums.com/showthread....-List-of-Items

  6. #6
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    24,813

    Re: Prevent Duplicates in Array

    Shuffling the full 59 numbers and taking the first 6 would be something like this..

    Code:
    Dim Lotto() As Integer 
    Dim allNumbers() As Integer = Enumerable.Range(1, 59).ToArray
    Dim RndLotto As New Random
    allNumbers = allNumbers.OrderBy(Function(x) RndLotto.NextDouble).ToArray
    Lotto = allNumbers.Take(6).ToArray

  7. #7
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    108,501

    Re: Prevent Duplicates in Array

    Quote Originally Posted by .paul. View Post
    Shuffling the full 59 numbers and taking the first 6 would be something like this..

    Code:
    Dim Lotto() As Integer 
    Dim allNumbers() As Integer = Enumerable.Range(1, 59).ToArray
    Dim RndLotto As New Random
    allNumbers = allNumbers.OrderBy(Function(x) RndLotto.NextDouble).ToArray
    Lotto = allNumbers.Take(6).ToArray
    No point calling ToArray multiple times. Only the last one is needed.

  8. #8
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    24,813

    Re: Prevent Duplicates in Array

    Quote Originally Posted by jmcilhinney View Post
    No point calling ToArray multiple times. Only the last one is needed.
    That would mean…

    Code:
    Dim allNumbers() As Integer
    Would have to be changed to…

    Code:
    Dim allNumbers
    Which would be an ienumerable of some undefined type

  9. #9
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    108,501

    Re: Prevent Duplicates in Array

    Or you could just do it all in one chain:
    vb.net Code:
    1. Dim rng As New Random
    2. Dim selectedNumbers = Enumerable.Range(1, 58).OrderBy(Function(n) rng.NextDouble()).Take(6).ToArray()
    Note that the original code used Random.Next(1, 59), so numbers in the range 1-58. Enumerable.Range takes the inclusive minimum and the count, rather than the inclusive minimum and the exclusive maximum, so you need to use 58 rather than 59.

  10. #10
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    24,813

    Re: Prevent Duplicates in Array

    👍 That’d work. But I thought the original random numbers were 1-58 and should’ve been 1-59 inclusive

  11. #11
    Karen Payne MVP kareninstructor's Avatar
    Join Date
    Jun 2008
    Location
    Oregon
    Posts
    6,671

    Re: Prevent Duplicates in Array

    You could use a HashSet, add values than use ToArray on the HashSet. In the example below is a proof of concept, you can add in the random values while written as shown below you know what the input and results are.

    For a console app, the HashSet should be in Main but for a Forms project working with a button you need this for the add and the result.

    Code:
    Module Program
        Private ReadOnly _hashSet As New HashSet(Of Integer)()
    
        Sub Main(args As String())
    
            Dim randomValues() As Integer = { 1, 1, 2, 3, 4, 5, 6, 6 }
    
            For Each value In randomValues
                _hashSet.Add(value)
            Next
    
            Dim values() As Integer = _hashSet.ToArray()
            Console.WriteLine(String.Join(",", values))
    
            Console.ReadLine()
    
        End Sub
    End Module

  12. #12
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    7,600

    Re: Prevent Duplicates in Array

    Quote Originally Posted by kareninstructor View Post
    You could use a HashSet, add values than use ToArray on the HashSet. In the example below is a proof of concept, you can add in the random values while written as shown below you know what the input and results are.

    For a console app, the HashSet should be in Main but for a Forms project working with a button you need this for the add and the result.

    Code:
    Module Program
        Private ReadOnly _hashSet As New HashSet(Of Integer)()
    
        Sub Main(args As String())
    
            Dim randomValues() As Integer = { 1, 1, 2, 3, 4, 5, 6, 6 }
    
            For Each value In randomValues
                _hashSet.Add(value)
            Next
    
            Dim values() As Integer = _hashSet.ToArray()
            Console.WriteLine(String.Join(",", values))
    
            Console.ReadLine()
    
        End Sub
    End Module
    This is definitely the right idea but that algorithm has a slight problem. OP implies that he wants to have an array of a specific size, 6 items in his case. Depending on how the random numbers are generated and fed into the HashSet, it could end up with less than 6 items if there were too many duplicates. I'd use your idea but with a different twist:-
    Code:
            Dim lotto As Integer() = New Func(Of Integer())(Function()
                                                                Dim hs As New HashSet(Of Integer)
                                                                Dim r As New Random
    
                                                                Do Until hs.Count = 6
                                                                    hs.Add(r.Next(1, 59))
                                                                Loop
                                                                Return hs.ToArray
                                                            End Function).Invoke
    
    
            Debug.WriteLine(String.Join(", ", lotto))
    The above code guarantees 2 things, that the array will always be 6 elements long and that each number is unique.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  13. #13
    PowerPoster ChrisE's Avatar
    Join Date
    Jun 2017
    Location
    Frankfurt
    Posts
    2,882

    Re: Prevent Duplicates in Array

    Quote Originally Posted by jmcilhinney View Post
    Or you could just do it all in one chain:
    vb.net Code:
    1. Dim rng As New Random
    2. Dim selectedNumbers = Enumerable.Range(1, 58).OrderBy(Function(n) rng.NextDouble()).Take(6).ToArray()
    Note that the original code used Random.Next(1, 59), so numbers in the range 1-58. Enumerable.Range takes the inclusive minimum and the count, rather than the inclusive minimum and the exclusive maximum, so you need to use 58 rather than 59.
    that is pretty cool JMC,
    here another twist based on your Idea
    Code:
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            MessageBox.Show(String.Join("-", Enumerable.Range(1, 58).OrderBy(Function(x) Guid.NewGuid()).Take(6).OrderBy(Function(x) x)))
        End Sub
    to hunt a species to extinction is not logical !
    since 2010 the number of Tigers are rising again in 2016 - 3900 were counted. with Baby Callas it's 3901, my wife and I had 2-3 months the privilege of raising a Baby Tiger.

  14. #14
    Karen Payne MVP kareninstructor's Avatar
    Join Date
    Jun 2008
    Location
    Oregon
    Posts
    6,671

    Re: Prevent Duplicates in Array

    Quote Originally Posted by Niya View Post
    This is definitely the right idea but that algorithm has a slight problem.
    True, I was not going there, figured my reply was to inject an alternate idea and leave the rest to the OP.

  15. #15
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    7,600

    Re: Prevent Duplicates in Array

    Quote Originally Posted by kareninstructor View Post
    True, I was not going there, figured my reply was to inject an alternate idea and leave the rest to the OP.
    Fair enough.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width