Wie generiere ich eine Zufallszahl zwischen a und b in Ruby?


189

Um beispielsweise eine Zufallszahl zwischen 3 und 10 zu generieren, verwende ich: rand(8) + 3

Gibt es eine schönere Möglichkeit, dies zu tun (so etwas wie rand(3, 10))?


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

@ Theo y - x + 1übrigens.
Nakilon

1
Versuchen Sie Ihre richtige Antwort auf 10 und 10 ** 24 als Limits: 0 wird sehr, sehr lange warten :)
xt.and.r

5
Dies funktioniert:rand(3..10)
Eikes

Antworten:


323

UPDATE: Ruby 1.9.3 Kernel#randakzeptiert auch Bereiche

rand(a..b)

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

Die Konvertierung in ein Array ist möglicherweise zu teuer und nicht erforderlich.


(a..b).to_a.sample

Oder

[*a..b].sample

Array # Beispiel

Standard in Ruby 1.8.7+.
Hinweis: wurde in 1.8.7 #choice genannt und in späteren Versionen umbenannt.

Das Generieren von Arrays erfordert jedoch Ressourcen, und die bereits geschriebene Lösung ist die beste, die Sie tun können.


Vielen Dank! Ich denke, ich werde bei der alten und der guten Methode bleiben :)
Misha Moroshko

32
Dies ist eine wirklich schlechte Idee, besonders wenn a und b unbekannte Größen haben. Versuchen Sie (100000000000000000..100000000000000) .to_a.sample und sehen Sie, was ich meine
:)

4
@pixelearth, wenn Sie eine bessere Idee haben, die der Frage entspricht, können Sie gerne posten.
Nakilon

rand(a..b)funktioniert nicht, es teilt sich : TypeError: can't convert Range into Integer. Es wird nicht einmal in Ruby 2.0 unterstützt
fguillen

2
@fguillen Es funktioniert für mich in 1.9.3, ich weiß nicht, warum es für Sie nicht funktioniert.
Michael Dorst

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

Wo aist Ihr niedrigster Wert und bist Ihr höchster Wert.


4
Der wesentliche Unterschied zu beachten ist , dass , wenn Sie gerade nennen rand()Sie anrufen Kernel#rand, die nur ein unterstütztes maxArgument. Wenn Sie einen Bereich übergeben möchten, müssen Sie diesen verwenden Random#rand, dh Sie müssen ihn auf diese Weise implementieren. +1
Grumpit

2
sollte hinzufügen, dass das oben Gesagte für 1.9.2 gilt
grumpit

Enthält es a und b?
Abhradip

12
rand(3..10)

Kernel # rand

Wenn max ein Bereich ist, gibt rand eine Zufallszahl zurück, wobei range.member? (Number) == true ist.


11

Beachten Sie einfach den Unterschied zwischen den Bereichsoperatoren:

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

3

Siehe diese Antwort: Es gibt in Ruby 1.9.2, aber nicht in früheren Versionen. Persönlich denke ich, dass Rand (8) + 3 in Ordnung ist, aber wenn Sie interessiert sind, schauen Sie sich die im Link beschriebene Zufallsklasse an.




2

Und hier ist ein kurzer Maßstab für beide #sampleund #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)

Tun rand(a..b)ist also das Richtige

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.