So erhalten Sie eine Zufallszahl in Ruby

Antworten:

952

Verwenden rand(range)

Aus Ruby-Zufallszahlen :

Wenn Sie eine zufällige Ganzzahl benötigen, um einen Wurf eines sechsseitigen Würfels zu simulieren, verwenden Sie : 1 + rand(6). Ein Roll-in-Craps könnte mit simuliert werden 2 + rand(6) + rand(6).

Wenn Sie nur einen zufälligen Float benötigen, rufen Sie einfach randohne Argumente auf.


Wie Marc-André Lafortune in seiner Antwort unten erwähnt (siehe oben) , hat Ruby 1.9.2 eine eigene RandomKlasse (die Marc-André selbst beim Debuggen unterstützt hat , daher das Ziel 1.9.2 für diese Funktion).

In diesem Spiel , in dem Sie 10 Zahlen erraten müssen , können Sie diese beispielsweise initialisieren mit:

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

Hinweis:

Aus diesem Grunde ist die äquivalent Random.new.rand(20..30)wäre 20 + Random.rand(11), da Random.rand(int)returns „eine zufällige ganze Zahl größer oder gleich null und kleiner als das Argument .“ 20..30Enthält 30, muss ich eine Zufallszahl zwischen 0 und 11 finden, ausgenommen 11.

VonC
quelle
2
Ist das nicht schrecklich nicht rubinartig? Ich dachte, alles ist ein Objekt, am wenigsten überraschend und das ...
Dan Rosenstark
1
@yar: Es ist ein bisschen "perlisch". Jetzt hat Ruby seine
Marc-André Lafortune
3
@VonC: Es ist großartig, dass Sie Ihre Antwort bearbeitet haben, um die neue RandomKlasse zu erwähnen , aber es ist eine schreckliche Idee, Random.newwie in Ihrem Beispiel mehrmals anzurufen . Ich habe meine Antwort bearbeitet, um dies anzugeben.
Marc-André Lafortune
2
@VonC ah :) Entschuldigung, wenn ich ein bisschen hart war, hat es mich nur überrascht
horseyguy
1
Random.rand nicht akzeptiert eine Reihe, eigentlich. (Seit 1.9.3, glaube ich.)
Ajedi32
591

Während Sie verwenden können rand(42-10) + 10, um eine Zufallszahl zwischen 10und 42(wobei 10 inklusive und 42 exklusiv ist) zu erhalten, gibt es seit Ruby 1.9.3 einen besseren Weg, wo Sie anrufen können:

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

Verfügbar für alle Versionen von Ruby, wenn Sie meinen backportsEdelstein benötigen .

Ruby 1.9.2 hat auch die RandomKlasse eingeführt, damit Sie Ihre eigenen Zufallszahlengeneratorobjekte erstellen können, und verfügt über eine nette API:

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

Die RandomKlasse selbst fungiert als Zufallsgenerator, sodass Sie direkt aufrufen:

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

Anmerkungen zu Random.new

In den meisten Fällen ist es am einfachsten, randoder zu verwenden Random.rand. Es ist eine wirklich schlechte Idee, jedes Mal einen neuen Zufallsgenerator zu erstellen, wenn Sie eine Zufallszahl möchten . Wenn Sie dies tun, erhalten Sie die zufälligen Eigenschaften des anfänglichen Seeding-Algorithmus, die im Vergleich zu den Eigenschaften des Zufallsgenerators selbst grausam sind .

Wenn Sie verwenden Random.new, sollten Sie es daher so selten wie möglich aufrufen , zum Beispiel einmal wieMyApp::Random = Random.new und überall verwenden.

Random.newFolgende Fälle sind hilfreich:

  • Sie schreiben einen Edelstein und möchten die Reihenfolge von rand/ nicht störenRandom.rand die Hauptprogramme möglicherweise verlassen
  • Sie möchten separate reproduzierbare Folgen von Zufallszahlen (z. B. eine pro Thread).
  • Sie möchten in der Lage sein, eine reproduzierbare Folge von Zufallszahlen zu speichern und fortzusetzen (einfach, da RandomObjekte gemarshallt werden können).
Marc-André Lafortune
quelle
1
Ausgezeichnet! +1. Ich habe meine eigene Antwort ausgefüllt, um diese neue Funktion widerzuspiegeln (und Ihren Beitrag mit Fehler # 3104 zu erwähnen;)).
VonC
1
@yar: Mein backportsJuwel ist einfach eine Sammlung von Methoden, die neu in RUby 1.8.7, 1.9.1, 1.9.2 sind, aber in Ruby implementiert sind. Ich verwende RubySpec, um sicherzustellen, dass die Ergebnisse mit Ruby kompatibel sind.
Marc-André Lafortune
@ Marc-André Lafortune, danke dafür. Es war mir immer seltsam, wie viel Ruby aufgrund von Geschwindigkeitsanforderungen in Nicht-Ruby (C oder was auch immer) implementiert ist. Aber sie sind die Pausen
Dan Rosenstark
5
Random.rand(10..42)funktioniert nicht. Die Random.randKlassenmethode akzeptiert keinen Bereich. (Ruby 1.9.2p180)
Horseyguy
1
@banister: Wow, ich war überzeugt, dass die neue API (Rand mit Bereich, Bytes usw.) direkt über das Random-Objekt verfügbar war. Rand mit Bereich wird in 1.9.3 sein, und ich werde eine Funktionsanforderung für Bytes stellen. Ich habe meine Antwort bearbeitet
Marc-André Lafortune
46

Wenn Sie nicht nur nach einer Zahl suchen, sondern auch nach Hex oder UUID, ist es erwähnenswert, dass das SecureRandomModul ActiveSupportin 1.9.2+ seinen Weg vom Rubinkern gefunden hat. Also ohne die Notwendigkeit eines vollständigen Frameworks:

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"

Es ist hier dokumentiert: Ruby 1.9.3 - Modul: SecureRandom (lib / securerandom.rb)

Thomas Fankhauser
quelle
Was ist, wenn Sie eine 4-stellige Zufallszahl benötigen?
Onurozgurozkan
1
onurozgurozkan Ich nehme anSecureRandom.random_number(1000..9999)
JayTarka
1
SecureRandom.random_number()nimmt keine Reichweite, also nein. Sie möchten wahrscheinlich etwas wie SecureRandom.random_number(10_000)(für 0-9999) oder SecureRandom.random_number(9_000)+1_000(für 1000-9999).
MWP
1
Random.rand (1000..9999)
Jesse Farmer
37

Mit der randMethode können Sie eine Zufallszahl generieren . Das an die randMethode übergebene Argument sollte ein integeroder a sein rangeund gibt eine entsprechende Zufallszahl innerhalb des Bereichs zurück:

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
MattD
quelle
Ich denke, Ihre rand(1..6)Lesungen sind klarer als die der Top-Antworten rand(6)+1.
Isomorphismen
21

Nun, ich habe es herausgefunden. Anscheinend gibt es eine eingebaute (?) Funktion namens rand:

rand(n + 1)

Wenn jemand mit einer detaillierteren Antwort antwortet, werde ich dies als die richtige Antwort markieren.

Mark A. Nicolosi
quelle
2
Ja, es ist im Kernel-Modul integriert.
Christoph Schiessl
17

Was ist damit?

n = 3
(0..n).to_a.sample
Rimian
quelle
3
Es sollte beachtet werden, dass das Erzeugen eines Arrays von Zahlen, wie es diese Lösung bietet, in großen Bereichen eine schreckliche Leistung aufweist, da es O (n) ist, während randes O (1) ist.
Travis
13

Einfachste Antwort auf die Frage:

rand(0..n)
sqrcompass
quelle
9

Sie können einfach verwenden random_number .

Wenn eine positive Ganzzahl als n angegeben wird, wird random_numbereine Ganzzahl zurückgegeben: 0 <= random_number<n.

Verwenden Sie es so:

any_number = SecureRandom.random_number(100) 

Die Ausgabe ist eine beliebige Zahl zwischen 0 und 100.

Tech-Träume
quelle
6
rand(6)    #=> gives a random number between 0 and 6 inclusively 
rand(1..6) #=> gives a random number between 1 and 6 inclusively

Beachten Sie, dass die Bereichsoption nur in neueren (glaube ich 1.9+) Versionen von Ruby verfügbar ist.

Josh
quelle
Ich glaube, die Bereichsoption ist nur in verfügbar ruby 1.9.3+. Es hat nicht funktioniert, 1.9.2als ich es zumindest versucht habe.
Batkins
6

Bereich = 10..50

Rand (Reichweite)

oder

range.to_a.sample

oder

range.to_a.shuffle (dies mischt das gesamte Array und Sie können eine Zufallszahl als erste oder letzte oder eine beliebige aus diesem Array auswählen, um eine zufällige auszuwählen.)

sumit
quelle
range.to_a.sampleist eine schreckliche Idee, wenn die Stichprobe groß ist.
Grzegorz
5

Sie können Rand (Reichweite) tun

x = rand(1..5)
Spürhund
quelle
4

Dieser Link wird diesbezüglich hilfreich sein.

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

Und etwas mehr Klarheit über die Zufallszahlen in Rubin;

Generieren Sie eine Ganzzahl von 0 bis 10

puts (rand() * 10).to_i

Generieren Sie eine Zahl von 0 bis 10 besser lesbar

puts rand(10)

Generieren Sie eine Zahl von 10 bis 15, einschließlich 15

puts rand(10..15)

Nicht zufällige Zufallszahlen

Generieren Sie bei jeder Programmausführung dieselbe Zahlenfolge

srand(5)

Generiere 10 Zufallszahlen

puts (0..10).map{rand(0..10)}
Sam
quelle
Sie können diesem Blog auch folgen, um Schritt für Schritt ein sehr klares Bild über zufällige Nummern in Rubin zu erhalten. sitepoint.com/tour-random-ruby
Sam
4

Einfache Möglichkeit, Zufallszahlen in Rubin zu erhalten, ist:

def random    
  (1..10).to_a.sample.to_s
end
ysk
quelle
2

Vielleicht hilft es dir. Ich benutze dies in meiner App

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

Es funktioniert gut für mich

Amarradi
quelle
2

Wie wäre es mit diesem?

num = Random.new
num.rand(1..n)
Juan Dela Cruz
quelle
1

Versuchen Sie die array#shuffleMethode zur Randomisierung

array = (1..10).to_a
array.shuffle.first
LuckyElf
quelle
1
Wenn Sie müssen ein ganzes Array machen, zumindest ersetzen .shuffle.firstmit .sample!
Camille Goudeseune
0

Vergessen Sie nicht, das RNG zuerst mit srand () zu setzen .

Liebach
quelle
2
Was passiert, wenn Sie srand () nicht aufrufen?
Alex B
21
srand wird automatisch aufgerufen, wobei der Startwert aus der aktuellen Zeit stammt, sofern er nicht bereits aufgerufen wurde.
Julian H