2

Suppose I had a int array

array=( 1 2 3 4 5 6 7 8 9 10 )

How would I pick a random number from the top 30% of the array, numbers 8, 9, or 10.

I know to pick a number at complete random in the array is:

${array[RANDOM % ${#array[@]}]}

However I don't know how to do pick a random element in a percentage of the array,

mklement0
  • 382,024
  • 64
  • 607
  • 775
Bob
  • 746
  • 3
  • 11
  • 26
  • 1
    Is your array sorted? – Floris Apr 26 '14 at 01:18
  • Consider `size*.7 + (rand % size)*.3`. In this is case that would be `7 + (rand % size)/3`. (This can lead to bias, but I don't think it'll be an issue here anymore than rand % size in general.) – user2864740 Apr 26 '14 at 01:30

2 Answers2

4
  1. Sort the array, in reverse:

    IFS=$'\n' sorted=($(sort -rn <<<"${array[*]}"))
    
  2. Figure out the number of eligible elements:

    n=$((${#sorted[@]}*3/10))
    
  3. Pick a random element:

    val=${sorted[RANDOM % $n]}
    
Community
  • 1
  • 1
nneonneo
  • 171,345
  • 36
  • 312
  • 383
1

Working off nneonneo's example...

So if I want to do something more dynamic I can do this:

percentage=0.3
IFS=$'\n' sorted=($(sort -rn <<<"${array[*]}"))
s=$(bc <<< $percentage*${#array[@]})
round=${s/.*}
round_ceil=$((round+1))
val=${sorted[RANDOM % $round_ceil]}

or do you see any bugs?

EDIT: I had to make a ceiling round instead of a floor round as floor rounds sometimes didn't produce a number.

Bob
  • 746
  • 3
  • 11
  • 26