【问题标题】:How to get a random number in Ruby如何在 Ruby 中获取随机数
【发布时间】:2010-09-16 22:35:54
【问题描述】:

如何在0n 之间生成一个随机数?

【问题讨论】:

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4 random


【解决方案1】:

使用rand(range)

来自Ruby Random Numbers

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

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


正如Marc-André Lafortunehis answer below (go upvote it) 中提到的那样,Ruby 1.9.2 has its own Random class(即 Marc-André 本人 helped to debug,因此该功能的 1.9.2 target)。

例如,在这个game where you need to guess 10 numbers 中,您可以使用:

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。

【讨论】:

  • 这不是非常不像红宝石吗?我认为一切都是一个对象,最不令人惊讶的是......
  • @yar:这有点“失败”。现在 Ruby 有了它的 Random 类(见我的回答)
  • @VonC:很高兴您编辑了您的答案以提及新的Random 类,但是像在您的示例中那样多次调用Random.new 是一个糟糕的主意。我已经编辑了我的答案来说明这一点。
  • @VonC 啊 :) 对不起,如果我有点苛刻,这让我感到惊讶
  • Random.rand 确实接受一个范围,实际上。 (我相信从 1.9.3 开始。)
【解决方案2】:

虽然您可以使用rand(42-10) + 10 获取1042 之间的随机数(其中10 包括在内,42 不包括在内),但自Ruby 1.9.3 以来有更好的方法,您可以在其中调用:

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

需要我的backports gem,可用于所有版本的 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 generator itself 的属性相比,这些属性是非常糟糕的。

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

Random.new 有用的情况如下:

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

【讨论】:

  • 太棒了! +1。我已经完成了自己的答案以反映该新功能(并提及您对 Bug #3104 的贡献;))。
  • @yar:我的backports gem 只是 RUby 1.8.7、1.9.1、1.9.2 的新方法的集合,但在 Ruby 中实现。我使用 RubySpec 来确保结果与 Ruby 兼容。
  • @Marc-André Lafortune,谢谢。由于速度要求,我一直很奇怪有多少 Ruby 是在非 Ruby(C 或其他)中实现的。但他们是休息时间
  • Random.rand(10..42) 不起作用。 Random.rand 类方法不接受范围。 (红宝石 1.9.2p180)
  • @banister:哇,我确信新的 api(带有范围、字节等的 rand)可以直接通过 Random 对象使用。带有范围的 rand 将在 1.9.3 中,我将对字节提出功能请求。我已经编辑了我的答案
【解决方案3】:

如果您不仅要查找数字,还要查找 hex 或 uuid,那么值得一提的是,SecureRandom 模块在 1.9.2+ 中找到了从 ActiveSupport 到 ruby​​ 核心的方式。所以不需要一个完整的框架:

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 - Module: SecureRandom (lib/securerandom.rb)

【讨论】:

  • 如果你需要4位随机数怎么办?
  • onurozgurozkan 我猜SecureRandom.random_number(1000..9999)
  • SecureRandom.random_number() 没有范围,所以没有。你可能想要SecureRandom.random_number(10_000)(0-9999)或SecureRandom.random_number(9_000)+1_000(1000-9999)之类的东西。
  • Random.rand(1000..9999)
【解决方案4】:

您可以使用rand 方法生成一个随机数。传递给rand 方法的参数应该是integerrange,并返回对应范围内的随机数:

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 更清晰。
【解决方案5】:

好吧,我想通了。显然有一个名为 rand 的内置 (?) 函数:

rand(n + 1)

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

【讨论】:

  • 是的,它内置在内核模块中。
【解决方案6】:

这个怎么样?

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

【讨论】:

  • 应该注意的是,像这个解决方案那样生成一个数字数组在大范围内的性能很差,因为它是 O(n) 而rand 是 O(1)。
【解决方案7】:

问题的最简单答案:

rand(0..n)

【讨论】:

    【解决方案8】:

    您可以简单地使用random_number

    如果给定一个正整数作为 n,random_number 返回一个整数:0 random_number

    像这样使用它:

    any_number = SecureRandom.random_number(100) 
    

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

    【讨论】:

      【解决方案9】:
      rand(6)    #=> gives a random number between 0 and 6 inclusively 
      rand(1..6) #=> gives a random number between 1 and 6 inclusively
      

      请注意,范围选项仅适用于较新的(我相信是 1.9+)版本的 ruby​​。

      【讨论】:

      • 我相信范围选项仅在ruby 1.9.3+ 中可用。至少当我尝试时,它在1.9.2 中不起作用。
      【解决方案10】:

      范围 = 10..50

      兰德(范围)

      range.to_a.sample

      range.to_a.shuffle(这将打乱整个数组,您可以按第一个或最后一个或从该数组中的任何一个随机数来选择随机数)

      【讨论】:

      • 当样本很大时,range.to_a.sample 是个糟糕的主意。
      【解决方案11】:

      你可以做 rand(range)

      x = rand(1..5)
      

      【讨论】:

        【解决方案12】:

        此链接将对此有所帮助;

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

        下面对 ruby​​ 中的随机数进行了更清晰的说明;

        生成一个从 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)}
        

        【讨论】:

        【解决方案13】:

        在 ruby​​ 中获取随机数的简单方法是,

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

        【讨论】:

          【解决方案14】:

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

          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

          对我来说很好用

          【讨论】:

            【解决方案15】:

            这个怎么样?

            num = Random.new
            num.rand(1..n)
            

            【讨论】:

              【解决方案16】:

              别忘了先用 srand() 播种 RNG。

              【讨论】:

              • 如果不调用 srand() 会发生什么?
              • srand 会自动调用,如果种子尚未调用,则种子来自当前时间。
              【解决方案17】:

              尝试array#shuffle随机化方法

              array = (1..10).to_a
              array.shuffle.first
              

              【讨论】:

              • 如果您必须制作整个数组,至少将.shuffle.first替换为.sample
              猜你喜欢
              • 1970-01-01
              • 2012-04-12
              • 2018-01-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多