如何使用Ruby在非连续范围内生成随机数?

Jay*_*ayX 3 ruby

例如,假设我有以下范围

5031..5032 6248..6249

如何在这两个范围内生成随机数?

Dig*_*oss 5

简单的方法:

(r1.to_a + r2.to_a).choice
Run Code Online (Sandbox Code Playgroud)

更快且更节省内存的通用解决方案将涉及计算总范围大小,生成随机数,然后将数字标准化到它所属的范围.

更新:好的,明白了.此解决方案适用于任意数量的范围,并且不会生成巨型数组或遍历范围本身.(它在Ranges数组上迭代两次,而不是Range元素数组.)

def rangerand *r
  r.inject(rand(
      r.inject(0) do |accum, rng|
        accum + rng.last - rng.first + 1
      end
    )) do |accum, rng|
      rngsize = rng.last - rng.first + 1
      return rng.first + accum if accum < rngsize
      accum - rngsize
    end
  # raise 'this "cannot happen"'
end

puts rangerand 1..3, 999..1001, 10_200..10_205
Run Code Online (Sandbox Code Playgroud)

嘿,我之前从未#inject在同一个表达中使用过两个s.

  • +1不是最简单的解决方案,但非常Rubyish :) (2认同)