Comment générer un nombre aléatoire entre a et b dans Ruby?


189

Pour générer un nombre aléatoire entre 3 et 10, par exemple, j'utilise: rand(8) + 3

Y a-t-il une meilleure façon de faire cela (quelque chose comme rand(3, 10))?


4
def my_rand(x, y); rand(y - x) + x; end
Theo

@Theo, y - x + 1au fait.
Nakilon

1
Essayez votre bonne réponse le 10 et le 10 ** 24 comme limites: 0 sera très très long :)
Sayan Malakshinov

5
Cela fonctionne:rand(3..10)
eikes

Réponses:


324

MISE À JOUR: Ruby 1.9.3 Kernel#randaccepte également les plages

rand(a..b)

http://www.rubyinside.com/ruby-1-9-3-introduction-and-changes-5428.html

La conversion en matrice peut être trop coûteuse et inutile.


(a..b).to_a.sample

Ou

[*a..b].sample

Array # sample

Standard dans Ruby 1.8.7+.
Remarque: a été nommé #choice dans la 1.8.7 et renommé dans les versions ultérieures.

Mais de toute façon, la génération d'un tableau nécessite des ressources, et la solution que vous avez déjà écrite est la meilleure que vous puissiez faire.


Merci! Je pense que je vais rester avec l'ancienne et la bonne méthode :)
Misha Moroshko

32
C'est une très mauvaise idée, surtout si vos a et b sont de tailles inconnues. Essayez (100000000000000000..100000000000000) .to_a.sample et voyez ce que je veux dire
:)

4
@pixelearth, si vous avez une meilleure idée de ce qui correspond à la question, vous êtes invités à poster.
Nakilon le

rand(a..b)ne fonctionne pas, il se divise: TypeError: can't convert Range into Integer. Il n'est même pas pris en charge dans Ruby 2.0
fguillen

2
@fguillen Cela fonctionne pour moi dans la version 1.9.3, je ne sais pas pourquoi cela ne fonctionne pas pour vous.
Michael Dorst

87
Random.new.rand(a..b) 

aest votre valeur la plus basse et bvotre valeur la plus élevée.


4
La différence importante à noter est que si vous appelez simplement, rand()vous appelez Kernel#rand, ce qui ne prend en charge qu'un maxargument. Si vous voulez passer une plage, vous devez utiliser Random#rand, ce qui signifie que vous devez implémenter de cette façon. +1
grumpit

2
devrait ajouter que ce qui précède s'applique à 1.9.2
grumpit

comprend-il a et b?
Abhradip

12
rand(3..10)

Noyau # rand

Lorsque max est un Range, rand renvoie un nombre aléatoire où range.member? (Number) == true.


11

Notez simplement la différence entre les opérateurs de plage:

3..10  # includes 10
3...10 # doesn't include 10

3

Voir cette réponse: il y en a dans Ruby 1.9.2, mais pas dans les versions antérieures. Personnellement, je pense que rand (8) + 3 est bien, mais si vous êtes intéressé, consultez la classe Random décrite dans le lien.




2

Et voici une référence rapide pour les deux #sampleet #rand:

irb(main):014:0* Benchmark.bm do |x|
irb(main):015:1*   x.report('sample') { 1_000_000.times { (1..100).to_a.sample } }
irb(main):016:1>   x.report('rand') { 1_000_000.times { rand(1..100) } }
irb(main):017:1> end
       user     system      total        real
sample  3.870000   0.020000   3.890000 (  3.888147)
rand  0.150000   0.000000   0.150000 (  0.153557)

Alors, faire rand(a..b)est la bonne chose

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.