Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Get 'x' number of unique, random, elements from an array

Little tricks

Get 'x' number of unique, random, elements from an array

by  KevinADC  Posted    (Edited  )
----------------------------
[small]ignore this section:
shuffle[/small]
----------------------------


Two ways (of many more I am sure) of returning "x" number of random yet unique elements from one array to a new list/array. First way uses the core module List::Util.

Code:
[link http://perldoc.perl.org/functions/use.html][black][b]use[/b][/black][/link] [green]List::Util[/green] [red]qw/[/red][purple]shuffle[/purple][red]/[/red][red];[/red]  
[link http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/link] [blue]@pop[/blue] = [red]([/red][fuchsia]1..100[/fuchsia][red])[/red][red];[/red]
[black][b]my[/b][/black] [blue]$samples[/blue] = [fuchsia]30[/fuchsia][red];[/red]
[black][b]my[/b][/black] [blue]@sample[/blue] = [red]([/red][maroon]shuffle[/maroon][red]([/red][blue]@pop[/blue][red])[/red][red])[/red][red][[/red][fuchsia]0..[/fuchsia][blue]$samples[/blue]-[fuchsia]1[/fuchsia][red]][/red][red];[/red]
[link http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/link] [red]"[/red][purple][blue]@sample[/blue][/purple][red]"[/red][red];[/red]

The shuffle() function randomly shuffles (mixes) the array. Then using an array slice [0..x] we take just the number of elements we want from the beginning of the shuffled array.

The second way uses a hash to insure uniqueness and the rand() function to get random elements from the array.

Code:
[link http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/link] [blue]@pop[/blue] = [red]([/red][fuchsia]1..100[/fuchsia][red])[/red][red];[/red]
[black][b]my[/b][/black] [blue]$samples[/blue] = [fuchsia]30[/fuchsia][red];[/red][gray][i]# see note below[/i][/gray]
[black][b]my[/b][/black] [blue]@sample[/blue] = [maroon]rand_sample[/maroon][red]([/red][fuchsia]30[/fuchsia],[blue]@pop[/blue][red])[/red][red];[/red]
[link http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/link] [red]"[/red][purple][blue]@sample[/blue][/purple][red]"[/red][red];[/red]
 
[link http://perldoc.perl.org/functions/sub.html][black][b]sub[/b][/black][/link] [maroon]rand_sample[/maroon] [red]{[/red]
   [black][b]my[/b][/black] [red]([/red][blue]$n[/blue],[blue]@n[/blue][red])[/red] = [red]([/red][link http://perldoc.perl.org/functions/shift.html][black][b]shift[/b][/black][/link],[blue]@_[/blue][red])[/red][red];[/red]
   [link http://perldoc.perl.org/functions/return.html][black][b]return[/b][/black][/link] [fuchsia]0[/fuchsia] [olive][b]unless[/b][/olive] [red]([/red][blue]$n[/blue] < [link http://perldoc.perl.org/functions/scalar.html][black][b]scalar[/b][/black][/link] [blue]@n[/blue][red])[/red][red];[/red][gray][i]# see note below  [/i][/gray]
   [black][b]my[/b][/black] [blue]%seen[/blue] = [red]([/red][red])[/red][red];[/red]
   [olive][b]until[/b][/olive] [red]([/red][link http://perldoc.perl.org/functions/keys.html][black][b]keys[/b][/black][/link] [blue]%seen[/blue] == [blue]$samples[/blue][red])[/red] [red]{[/red]
      [blue]$seen[/blue][red]{[/red][blue]$pop[/blue][red][[/red][link http://perldoc.perl.org/functions/rand.html][black][b]rand[/b][/black][/link] [blue]@pop[/blue][red]][/red][red]}[/red]=[fuchsia]1[/fuchsia][red];[/red]
   [red]}[/red]    
   [black][b]return[/b][/black][red]([/red][black][b]keys[/b][/black] [blue]%seen[/blue][red])[/red][red];[/red]
[red]}[/red]

The "until" loop continues until we have the requested number of samples from the original array. Because hash keys must be unique, we get a list of unrepeated samples from the original array.

[color #ff0000]Note: this value must be less than the length of the array or the script will go into an infinte loop. It could be equal but then all you would be doing is shuffling the original array.[/color]




Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top