Come ottenere un numero casuale in Ruby


Risposte:


952

Uso rand(range)

Dai numeri casuali di Ruby :

Se avete bisogno di un intero casuale per simulare un lancio di un dado a sei facce, utilizza: 1 + rand(6). È possibile simulare un lancio di dadi 2 + rand(6) + rand(6).

Infine, se hai solo bisogno di un float casuale, chiama semplicemente randsenza argomenti.


Come Marc-André Lafortune menziona nella sua risposta di seguito (vai a votarla) , Ruby 1.9.2 ha una sua Randomclasse (che lo stesso Marc-André ha contribuito al debug , quindi l' obiettivo 1.9.2 per quella caratteristica).

Ad esempio, in questo gioco in cui devi indovinare 10 numeri , puoi inizializzarli con:

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

Nota:

Questo è il motivo per cui l'equivalente di Random.new.rand(20..30)sarebbe 20 + Random.rand(11), poiché Random.rand(int)restituisce "un numero intero casuale maggiore o uguale a zero e inferiore all'argomento ". 20..30include 30, devo trovare un numero casuale compreso tra 0 e 11, escluso 11.


2
Non è terribilmente non rubino? Ho pensato che tutto fosse un oggetto, almeno una sorpresa e che ...
Dan Rosenstark, il

1
@yar: è un po '"perlish". Ora Ruby ha la sua classe Casuale (vedi la mia risposta)
Marc-André Lafortune,

3
@VonC: È fantastico che tu abbia modificato la tua risposta per menzionare la nuova Randomclasse, ma è una pessima idea chiamare Random.newpiù volte come nel tuo esempio. Ho modificato la mia risposta per affermarlo.
Marc-André Lafortune,

2
@VonC ah :) scusa se sono stato un po 'duro, mi ha sorpreso
Horseyguy,

1
Random.rand non accetta un intervallo, in realtà. (Dall'1.9.3, credo.)
Ajedi32,

591

Mentre puoi usare rand(42-10) + 10per ottenere un numero casuale tra 10e 42(dove 10 è inclusivo e 42 esclusivo), c'è un modo migliore rispetto a Ruby 1.9.3, dove puoi chiamare:

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

Disponibile per tutte le versioni di Ruby richiedendo la mia backportsgemma.

Ruby 1.9.2 ha anche introdotto la Randomclasse in modo da poter creare i propri oggetti generatori di numeri casuali e ha una bella API:

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

La Randomclasse stessa funge da generatore casuale, quindi chiami direttamente:

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

Note su Random.new

Nella maggior parte dei casi, il più semplice è usare rando Random.rand. Creare un nuovo generatore casuale ogni volta che vuoi un numero casuale è una pessima idea . Se lo fai, otterrai le proprietà casuali dell'algoritmo di seeding iniziale che sono atroci rispetto alle proprietà del generatore casuale stesso .

Se lo usi Random.new, dovresti quindi chiamarlo il più raramente possibile , ad esempio una volta MyApp::Random = Random.newe usarlo ovunque.

I casi in cui Random.newè utile sono i seguenti:

  • stai scrivendo una gemma e non vuoi interferire con la sequenza di rand/ su Random.randcui i programmi principali potrebbero fare affidamento
  • vuoi sequenze riproducibili separate di numeri casuali (dicine uno per thread)
  • vuoi essere in grado di salvare e riprendere una sequenza riproducibile di numeri casuali (facile come gli Randomoggetti possono essere smistati)

1
Eccellente! +1. Ho completato la mia risposta per riflettere quella nuova funzione (e menzionando il tuo contributo con Bug # 3104;)).
VonC,

1
@yar: La mia backportsgemma è semplicemente una raccolta di metodi nuovi per RUby 1.8.7, 1.9.1, 1.9.2, ma implementati in Ruby. Uso RubySpec per assicurarmi che i risultati siano compatibili con Ruby.
Marc-André Lafortune,

@ Marc-André Lafortune, grazie per quello. È sempre stato strano per me quanta parte di Ruby è implementata in non Ruby (C o altro) a causa dei requisiti di velocità. Ma sono le pause
Dan Rosenstark,

5
Random.rand(10..42)non funziona. Il Random.randmetodo class non accetta un intervallo. (Ruby 1.9.2p180)
Horseyguy,

1
@banister: wow, ero convinto che il nuovo api (rand con range, byte, ecc ...) fosse disponibile direttamente attraverso l'oggetto Random. rand con range sarà in 1.9.3 e farò una richiesta di funzionalità per byte. Ho modificato la mia risposta
Marc-André Lafortune,

46

Se non stai solo cercando un numero, ma anche hex o uuid, vale la pena ricordare che il SecureRandommodulo ha trovato la sua strada dal ActiveSupportcore ruby ​​in 1.9.2+. Quindi senza la necessità di un quadro completo:

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"

È documentato qui: Ruby 1.9.3 - Modulo: SecureRandom (lib / securerandom.rb)


Che dire se hai bisogno di un numero casuale di 4 cifre?
onurozgurozkan,

1
onurozgurozkan presumoSecureRandom.random_number(1000..9999)
JayTarka,

1
SecureRandom.random_number()non prende una distanza, quindi no. Probabilmente vorresti qualcosa del tipo SecureRandom.random_number(10_000)(per 0-9999) o SecureRandom.random_number(9_000)+1_000(per 1000-9999).
mwp,

1
Random.rand (1000..9999)
Jesse Farmer,

37

È possibile generare un numero casuale con il randmetodo L'argomento passato al randmetodo dovrebbe essere un integero un rangee restituisce un numero casuale corrispondente all'interno dell'intervallo:

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

Penso che usare le tue rand(1..6)letture sia più chiaro di quello della risposta migliore rand(6)+1.
isomorfismi

21

Bene, l'ho capito. Apparentemente esiste una funzione incorporata (?) Chiamata rand:

rand(n + 1)

Se qualcuno risponde con una risposta più dettagliata, la segnerò come risposta corretta.


2
Sì, è integrato nel modulo Kernel.
Christoph Schiessl,

17

Che dire di questo?

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

3
Va notato che la generazione di una matrice di numeri come questa soluzione fornisce prestazioni terribili su grandi intervalli poiché è O (n) mentre randè O (1).
Travis,


9

Puoi semplicemente usare random_number.

Se un numero intero positivo viene dato come n, random_numberrestituisce un numero intero: 0 <= random_number<n.

Usalo in questo modo:

any_number = SecureRandom.random_number(100) 

L'output sarà qualsiasi numero compreso tra 0 e 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

Nota che l'opzione range è disponibile solo nelle versioni più recenti (1.9+ credo) di ruby.


Credo che l'opzione di gamma sia disponibile solo in ruby 1.9.3+. Non ha funzionato 1.9.2quando ho provato almeno.
Batkins,

6

intervallo = 10..50

rand (range)

o

range.to_a.sample

o

range.to_a.shuffle (questo mescolerà l'intero array e puoi scegliere un numero casuale dal primo o dall'ultimo o qualsiasi altro da questo array per sceglierne uno casuale)


range.to_a.sampleè una pessima idea quando il campione è grande.
Grzegorz,


4

Questo link sarà utile al riguardo;

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

E un po 'più di chiarezza di seguito sui numeri casuali in rubino;

Genera un numero intero compreso tra 0 e 10

puts (rand() * 10).to_i

Genera un numero da 0 a 10 In un modo più leggibile

puts rand(10)

Genera un numero da 10 a 15, incluso 15

puts rand(10..15)

Numeri casuali non casuali

Genera la stessa sequenza di numeri ogni volta che viene eseguito il programma

srand(5)

Genera 10 numeri casuali

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

Inoltre è possibile seguire questo blog per immagini passo dopo passo molto chiare su numeri casuali in rubino; sitepoint.com/tour-random-ruby
Sam

4

Il modo semplice per ottenere un numero casuale in ruby ​​è,

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

2

Forse ti aiuta. Lo uso nella mia 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

Funziona bene per me



1

Prova il array#shufflemetodo per la randomizzazione

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

1
Se è necessario creare un intero array, almeno sostituirlo .shuffle.firstcon .sample!
Camille Goudeseune,

0

Non dimenticare di seminare prima l'RNG con srand () .


2
Cosa succede se non chiami srand ()?
Alex B

21
srand viene chiamato automaticamente con il seed dell'ora corrente se non era già stato chiamato.
Julian H
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.