如何在Ruby中获得随机数


Answers:


951

采用 rand(range)

Ruby随机数开始

如果您需要一个随机整数来模拟六边形骰子的卷,请使用:1 + rand(6)。掷骰子可以用来模拟2 + rand(6) + rand(6)

最后,如果您只需要一个随机浮点数,则只需rand不带任何参数的调用即可。


正如Marc-AndréLafortune下面的回答中提到的(支持它)Ruby 1.9.2具有自己的Random(Marc-André自己进行了调试,因此该功能的目标1.9.2)。

例如,在这个游戏中,您需要猜测10个数字,可以使用以下方法初始化它们:

10.times.map{ 20 + Random.rand(11) } 
#=> [26, 26, 22, 20, 30, 26, 23, 23, 25, 22]

注意:

这就是为什么相当于Random.new.rand(20..30)20 + Random.rand(11),因为Random.rand(int)回报“的随机整数大于或等于零且小于参数。” 20..30包括30,我需要给出一个介于0和11之间的随机数(不包括11)。


2
这不是很像红宝石吗?我以为一切都是物体,最少的惊喜……
Dan Rosenstark 2010年

1
@yar:有点“完成”。现在Ruby有它的Random类(见我的回答)
马克-安德烈·Lafortune

3
@VonC:很高兴您编辑答案来提及新Random课程,但是Random.new像您的示例中那样多次调用是一个很糟糕的主意。我已经编辑了答案以说明这一点。
马克-安德烈·Lafortune

2
@VonC ah :)对不起,如果我有点苛刻,这只会令我感到惊讶
horseyguy 2011年

1
Random.rand 确实接受范围。(我相信,自1.9.3起。)
Ajedi32

591

虽然您可以rand(42-10) + 10用来获取介于10和之间的随机数42(其中10包括10,42排除在外),但是自Ruby 1.9.3起,有一种更好的方法可以调用:

rand(10...42) # => 13

需要我的backportsgem即可用于所有版本的Ruby 。

Ruby 1.9.2还引入了Random该类,因此您可以创建自己的随机数生成器对象并具有一个不错的API:

r = Random.new
r.rand(10...42) # => 22
r.bytes(3) # => "rnd"

Random类本身作为一个随机数生成器,让您直接拨打:

Random.rand(10...42) # => same as rand(10...42)

注意事项 Random.new

在大多数情况下,最简单的方法是使用randRandom.rand。每次想要一个随机数时都创建一个新的随机数生成器是一个非常糟糕的主意。如果执行此操作,则将获得初始播种算法的随机属性,与随机生成器本身的属性相比,这些属性非常糟糕。

如果使用Random.new,则应尽可能少地调用它,例如一次调用它,MyApp::Random = Random.new然后在其他任何地方使用它。

Random.new以下是有帮助的情况:

  • 您正在编写gem,并且不想干扰主程序可能依赖的rand/ 序列Random.rand
  • 您需要单独的可重现的随机数序列(例如每个线程一个)
  • 您希望能够保存和恢复可重复的随机数序列(因为Random可以将对象编组很容易)

1
优秀的!+1。我已经完成了自己的回答,以反映该新功能(并提及您对Bug#3104的贡献;)。
VonC 2010年

1
@yar:我的backportsgem只是RUby 1.8.7、1.9.1、1.9.2的新方法集合,但是在Ruby中实现。我使用RubySpec来确保结果与Ruby兼容。
马克-安德烈·Lafortune

@Marc-AndréLafortune,谢谢。由于速度要求,在非Ruby(C或其他)中实现了多少Ruby对我来说一直很奇怪。但它们是
突破口

5
Random.rand(10..42)不起作用。本Random.rand类方法不接受范围。(Ruby 1.9.2p180)
horseyguy

1
@banister:哇,我坚信可以通过Random对象直接使用新的api(带有范围,字节等的rand)。范围的rand将在1.9.3中,我将对字节进行功能请求。我已经编辑我的答案
马克-安德烈·Lafortune

46

如果您不仅要查找数字,还需要查找十六进制或uuid,则值得一提的是,该SecureRandom模块已ActiveSupport在1.9.2+中找到了通往红宝石核心的道路。因此,不需要完整的框架:

require 'securerandom'

p SecureRandom.random_number(100) #=> 15
p SecureRandom.random_number(100) #=> 88

p SecureRandom.random_number #=> 0.596506046187744
p SecureRandom.random_number #=> 0.350621695741409

p SecureRandom.hex #=> "eb693ec8252cd630102fd0d0fb7c3485"

它在此处记录:Ruby 1.9.3-模块:SecureRandom(lib / securerandom.rb)


如果您需要4位随机数怎么办?
onurozgurozkan 2014年

1
我假设SecureRandom.random_number(1000..9999)
onurozgurozkan

1
SecureRandom.random_number()没有范围,所以不。您可能想要类似SecureRandom.random_number(10_000)(对于0-9999)或SecureRandom.random_number(9_000)+1_000(对于1000-9999)。
mwp 2015年

1
Random.rand(1000..9999)
杰西·法默

37

您可以使用该rand方法生成一个随机数。传递给rand方法的参数应为an integer或a range,并返回范围内的相应随机数:

rand(9)       # this generates a number between 0 to 8
rand(0 .. 9)  # this generates a number between 0 to 9
rand(1 .. 50) # this generates a number between 1 to 50
#rand(m .. n) # m is the start of the number range, n is the end of number range

我认为使用您的rand(1..6)读物比头一个答案更清晰rand(6)+1
同构2014年

21

好吧,我知道了。显然有一个称为rand的内置(?)函数:

rand(n + 1)

如果有人回答的答案更详细,我会将其标记为正确答案。


2
是的,它内置在内核模块中。
Christoph Schiessl,

17

那这个呢?

n = 3
(0..n).to_a.sample

3
应该注意的是,像O(n)一样rand是O(1)时,像这样的解决方案生成数字数组在大范围内具有可怕的性能。
特拉维斯


9

您可以简单地使用 random_number

如果给定正整数n,则random_number返回整数:0 <= random_number<n。

像这样使用它:

any_number = SecureRandom.random_number(100) 

输出将是0到100之间的任何数字。


6
rand(6)    #=> gives a random number between 0 and 6 inclusively 
rand(1..6) #=> gives a random number between 1 and 6 inclusively

请注意,range选项仅在红宝石的新版本(我相信是1.9+)中可用。


我相信range选项仅在中可用ruby 1.9.3+1.9.2至少当我尝试时,它没有用。
巴特金斯

6

范围= 10..50

兰德(范围)

要么

range.to_a.sample

要么

range.to_a.shuffle(这将对整个数组进行混洗,您可以按此数组的第一个或最后一个或任意一个随机数选择一个随机数)


range.to_a.sample当样本很大时,这是一个可怕的主意。
Grzegorz


4

此链接将对此有所帮助;

http://ruby-doc.org/core-1.9.3/Random.html

以下是关于红宝石中随机数的更多说明;

生成一个从0到10的整数

puts (rand() * 10).to_i

以更易读的方式生成从0到10的数字

puts rand(10)

生成10到15之间的数字,包括15

puts rand(10..15)

非随机数

每次运行程序时生成相同的数字序列

srand(5)

产生10个随机数

puts (0..10).map{rand(0..10)}

您也可以按照此博客逐步了解有关红宝石中随机编号的清晰图片;sitepoint.com/tour-random-ruby
山姆

4

获得红宝石中随机数的简单方法是

def random    
  (1..10).to_a.sample.to_s
end

2

也许对您有帮助。我在我的应用程序中使用它

https://github.com/rubyworks/facets
class String

  # Create a random String of given length, using given character set
  #
  # Character set is an Array which can contain Ranges, Arrays, Characters
  #
  # Examples
  #
  #     String.random
  #     => "D9DxFIaqR3dr8Ct1AfmFxHxqGsmA4Oz3"
  #
  #     String.random(10)
  #     => "t8BIna341S"
  #
  #     String.random(10, ['a'..'z'])
  #     => "nstpvixfri"
  #
  #     String.random(10, ['0'..'9'] )
  #     => "0982541042"
  #
  #     String.random(10, ['0'..'9','A'..'F'] )
  #     => "3EBF48AD3D"
  #
  #     BASE64_CHAR_SET =  ["A".."Z", "a".."z", "0".."9", '_', '-']
  #     String.random(10, BASE64_CHAR_SET)
  #     => "xM_1t3qcNn"
  #
  #     SPECIAL_CHARS = ["!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "_", "=", "+", "|", "/", "?", ".", ",", ";", ":", "~", "`", "[", "]", "{", "}", "<", ">"]
  #     BASE91_CHAR_SET =  ["A".."Z", "a".."z", "0".."9", SPECIAL_CHARS]
  #     String.random(10, BASE91_CHAR_SET)
  #      => "S(Z]z,J{v;"
  #
  # CREDIT: Tilo Sloboda
  #
  # SEE: https://gist.github.com/tilo/3ee8d94871d30416feba
  #
  # TODO: Move to random.rb in standard library?

  def self.random(len=32, character_set = ["A".."Z", "a".."z", "0".."9"])
    chars = character_set.map{|x| x.is_a?(Range) ? x.to_a : x }.flatten
    Array.new(len){ chars.sample }.join
  end

end

https://github.com/rubyworks/facets/blob/5569b03b4c6fd25897444a266ffe25872284be2b/lib/core/facets/string/random.rb

这对我来说可以




By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.