# VBForums CodeBank > CodeBank - Visual Basic .NET >  Unique, Random Selections from a List

## jmcilhinney

C #version here.

This is pretty simple stuff but it's come up more than once so I thought I'd post it.  If you want to randomly select objects from a list where each object can only be chosen once you can use a collection and a Random object to select indexes into that collection.  Below is an example using an ArrayList and the numbers 1 to 10.  The objects could be anything though, not just numbers.  In .NET 2.0 you'd more likely use a Generic.List(Of T) rather than an ArrayList.
VB Code:
Dim list As New ArrayList         For i As Integer = 1 To 10            'Add the numbers to the collection.            list.Add(i)        Next i         Dim rand As New Random        Dim index As Integer        Dim item As Object         'Display the items in random order.        While list.Count > 0            'Choose a random index.            index = rand.Next(0, list.Count)             'Get the item at that index.            item = list(index)             'Remove the item so that it cannot be chosen again.            list.RemoveAt(index)             'Display the item.            MessageBox.Show(item.ToString())        End While

----------


## uniquegodwin

Hi Jm,
Nice handy code  :Smilie:  Well done  :Smilie: 

I think a lot of people need code snipplets like this for simple things  :Smilie:  would be useful during an emergency or tensed situation...when we actually cant sit and try making it due to all the pressures.

----------


## shakti5385

Nice Code  :Thumb:

----------


## James Bearss

thanks, this helped

----------


## newpat

is that when gen a new number, the old value in item.toString will lose?

----------


## FooFighter

Would someone mind explaining how I'd go about using this code to extract 5 unique values from it at one time?

----------


## jmcilhinney

> Would someone mind explaining how I'd go about using this code to extract 5 unique values from it at one time?


You can't get 5 at a time.  You can only get 1 at a time so you'd do that 5 times.  Instead of a While loop emptying the collection you'd use a For loop from 1 to 5.

----------


## FooFighter

I'm fairly new to visual basic. How exactly would I accomplish what you said? I've been trying different things and keep getting errors.

I have 5 labels. I'm trying to put 1 unique number between 1 and 10 into each label with the click of one button.

----------


## bigdave

Foofighter, I would use something like this



```
dim selected(9) as boolean
dim thisnumber, i as integer
dim result(4) as integer

For i = 0 To 4
      Do
      thisnumber = (Int(Rnd() * 10))

      Loop While selected(thisnumber) = True
      selected(thisnumber) = True
      result(i) = thisnumber 
	  
Next
```

this will leave 5 random numbers in the result() array which you can then move to a label using label#.text=result(#) (where # is the relevent number)

Whilst this will work, I do think the first post would be a better and prettier way of doing it.

----------


## FooFighter

I'm not using labels. I'm using 5 pictureboxes with an imagelist that contains the 52 card images. Also I have no idea where I'd put that code you listed.

----------


## jmcilhinney

vb.net Code:
Private Function GetRandomCardImages(ByVal count As Integer) As Image()
    'Create the full list of Images here.
     Dim upperBound As Integer = count - 1
    Dim selections(upperBound) As Image
    For index As Integer = 0 To upperBound Step 1
        selections(index) = 'Get random Image here.
    Next index
     Return selections
End Function

----------


## sonia.sardana

U can also use shuffle algorithm to return unique  random numbers
http://www.*************s.com/vb-net...m-numbers.html

----------


## i00

I would do it with linQ:



```
       Dim list As New ArrayList

        For i As Integer = 1 To 10
            'Add the numbers to the collection.
            list.Add(i)
        Next i

        Randomize()

        Dim RandomList = From RndList In list _
               Select RndList _
               Order By Rnd()

        For Each item In RandomList
            MsgBox(item)
        Next
```

----------


## JimTheNim

Fantastic code, and saved me countless hours fannying around with the code I already tried. How would you adapt this to be omit a range of numbers from the selection?

I need to be able to draw a random number between, say, 1 to 1000. These numbers relate to 14 teams (each with their own range of numbers).

If team 2 is drawn first, and their number range is 123 to 215, I need to make sure that numbers 123 to 215 are not included in the next random selection of the remaining numbers of 1-122 and 216-1000.

It's a doozy!  :Confused:

----------


## i00

well if you want to wouldn't u randomly pick one of the teams then - rather than randomly pick one of the players from these teams?

----------


## i00

also if a team has more players they have an advantage of being picked sooner than a team with less players

----------


## i00

But maybe something like this - this method will have equal probability of picking each team also:


vb Code:
Private Class Players
        Public Team As String
        Public Name As String
        Public Sub New(ByVal Team As String, ByVal Name As String)
            Me.Team = Team
            Me.Name = Name
        End Sub
    End Class
     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
          Dim list As New List(Of Players)
         list.Add(New Players("Broncos", "Antonio Winterstein"))
        list.Add(New Players("Broncos", "Karmichael Hunt"))
        list.Add(New Players("Broncos", "Alex Glenn"))
        list.Add(New Players("Broncos", "Justin Hodges"))
        list.Add(New Players("Broncos", "Jharal Yow Yeh"))
        list.Add(New Players("Broncos", "Darren Lockyer"))
        list.Add(New Players("Broncos", "Peter Wallace"))
        list.Add(New Players("Broncos", "Nick Kenny"))
        list.Add(New Players("Broncos", "Andrew McCullough"))
        list.Add(New Players("Broncos", "David Taylor"))
        list.Add(New Players("Broncos", "Tonie Carroll"))
        list.Add(New Players("Broncos", "Sam Thaiday"))
        list.Add(New Players("Broncos", "Corey Parker"))
        list.Add(New Players("Broncos", "Lagi Setu"))
        list.Add(New Players("Broncos", "Ben Te’o"))
        list.Add(New Players("Broncos", "Josh McGuire"))
        list.Add(New Players("Broncos", "Ashton Sims"))
         list.Add(New Players("St George", "Darius Boyd"))
        list.Add(New Players("St George", "Matt Cooper"))
        list.Add(New Players("St George", "Neville Costigan"))
        list.Add(New Players("St George", "Ben Creagh"))
        list.Add(New Players("St George", "Nick Emmett"))
         Randomize()
         Dim RandomList = From RndList In (From xitem In list Select xitem Group By xitem.Team Into First()) _
               Select RndList _
               Order By Rnd()
         For Each item In RandomList
            MsgBox(item.Team)
        Next
    End Sub

I have done it like the above ... as from your question it sounds like u just have a collection of players rather than a separate one of teams?

----------


## JimTheNim

Thank you i00 for your response,

I tried to give an example on how I thought it could work but it wasn't the whole facts. What I actually need is:

We have a number of field computer technicians, based out of 14 national centres, who also sell products to our customers. For every product they sell their centre gets a ticket.

It's these tickets that get drawn at the end of each month, to decide which centre gets the prize. There are 5 prizes to be won each month, and only one prize per centre.

Hence why one centre may only sell 30 items - and get 30 tickets, another centre may get 230 tickets. This is why it would be a higher probability that one team could win over another - because they had sold more items.

I'll have play around with your code though to see if there is anything I can do. 
Thank you for your help.

----------


## i00

Something like this then should do the trick  :Smilie: 


vb Code:
Private Class Tickets
        Public TicketNo As String
        Public NationalCentre As String
        Public inValidated As Boolean = False
        Public Sub New(ByVal TicketNo As String, ByVal NationalCentre As String)
            Me.TicketNo = TicketNo
            Me.NationalCentre = NationalCentre
        End Sub
    End Class
     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim TicketsList As New List(Of Tickets)
        'fill with some tickets
        For i = 1 To 100
            Select Case i
                Case Is < 10
                    TicketsList.Add(New Tickets(i, "Seven Hills"))
                Case Is < 30
                    TicketsList.Add(New Tickets(i, "Morningside"))
                Case Is < 50
                    TicketsList.Add(New Tickets(i, "Hawthorne"))
                Case Is < 80
                    TicketsList.Add(New Tickets(i, "Coorparoo"))
                Case Is < 89
                    TicketsList.Add(New Tickets(i, "Park Road"))
                Case Else
                    TicketsList.Add(New Tickets(i, "Brisbane CBD"))
            End Select
        Next
         Dim ListOfElligableNationalCentres As New List(Of String)
        ListOfElligableNationalCentres = (From xitem In (From xitem2 In TicketsList Select xitem2 Group By xitem2.NationalCentre Into First()) Select xitem.NationalCentre).ToList
           Randomize()
        Dim TicketAndPortions = From xItem In TicketsList _
                                Join xItem2 In ListOfElligableNationalCentres On xItem.NationalCentre Equals xItem2 _
                                Order By Rnd()
        For i = 1 To 5
            Dim SelectedNationalCenter As String = TicketAndPortions(0).xItem.NationalCentre
            MsgBox(SelectedNationalCenter)
            ListOfElligableNationalCentres.Remove(SelectedNationalCenter)
        Next
    End Sub

----------


## Mynotoar

Hey, thank you very much - I'm posting here so I've got this bookmarked.

----------


## davebold370

This code is very impressive. I like it a lot. I am new to the world of programming and I am trying to figure out how to use this with three text files to pull words from each to create some kind of structure. One text file is for nouns, the other is for smaller items like or/and/but,etc..., the last one is verbs. I want to be able to imput the limits and have computer generate something like a poem out of those three files. Thus a limit per line. My first step would be pulling it out of three files. How would i go about doing this?

----------


## jmcilhinney

> This code is very impressive. I like it a lot. I am new to the world of programming and I am trying to figure out how to use this with three text files to pull words from each to create some kind of structure. One text file is for nouns, the other is for smaller items like or/and/but,etc..., the last one is verbs. I want to be able to imput the limits and have computer generate something like a poem out of those three files. Thus a limit per line. My first step would be pulling it out of three files. How would i go about doing this?


Assuming that you have one word per line in the files, you can call File.ReadAllLines to read the file into a String array.  You can then call ToList on that to get a List(Of String) and that's your collection, from which you can select and remove items.

----------


## davebold370

@jmcilhinney Thanks

----------


## OysterD3

What is the code if I click a button.
and it will random a picture within 10 of it without repeating?

----------


## jmcilhinney

> What is the code if I click a button.
> and it will random a picture within 10 of it without repeating?


I'm not a code-writing service.  I've demonstrated principles here in this thread.  You can use those principles to achieve your aim.  If you make an effort and encounter a specific issue along the way then I'm quite willing to help with that, although you should be starting a new thread of your own for that.  If you are just waiting for someone to write your code for you then you'll be waiting a long time for me.

----------

