简体   繁体   中英

Ruby: using `.each` or `.step`, step forward a random amount for each iteration

(Also open to other similar non-Rails methods)

Given (0..99) , return entries that are randomly picked in-order.

Example results:

0, 5, 11, 13, 34..

3, 12, 45, 67, 87

0, 1, 2, 3, 4, 5.. (very unlikely, of course)

Current thought:

(0..99).step(rand(0..99)).each do |subindex|
  array.push(subindex)
end

However, this sets a single random value for all the steps whereas I'm looking for each step to be random.

Get a random value for the number of elements to pick, randomly get this number of elements, sort.

(0..99).to_a.sample((0..99).to_a.sample).sort
#⇒ [7, 20, 22, 29, 45, 48, 57, 61, 62, 76, 80, 82]

Or, shorter (credits to @Stefan):

(0..99).to_a.sample(rand(0..99)).sort
#⇒ [7, 20, 22, 29, 45, 48, 57, 61, 62, 76, 80, 82]

Or, in more functional manner:

λ = (0..99).to_a.method(:sample)
λ.(λ.()).sort

To feed exactly N numbers:

N = 10
(0..99).to_a.sample(N).sort
#⇒ [1, 5, 8, 12, 45, 54, 60, 65, 71, 91]

There're many ways to achieve it.

For example here's slow yet simple one:

# given `array`
random_indexes = (0...array.size).to_a.sample(rand(array.size))
random_indexes.sort.each { |i| puts array[i] }

Or why don't you just:

array.each do |value|
  next if rand(2).zero?
  puts value
end

Or you could use Enumerator#next random number of times.

Below example returns a sorted array with random entries from given range based on randomly picked true or false from array [true, false] :

(0..99).select { [true, false].sample }
 => [0, 3, 12, 13, 14, 17, 20, 24, 26, 28, 30, 32, 34, 35, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 53, 54, 55, 56, 58, 59, 60, 61, 62, 65, 67, 69, 70, 71, 79, 81, 84, 86, 91, 93, 94, 95, 98, 99]

To reduce the chances of a bigger array being returned, you can modify your true/false array to include more falsey values:

(0..99).select { ([true] + [false] * 9).sample }
 => [21, 22, 28, 33, 37, 58, 59, 63, 77, 85, 86]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM