Как сгенерировать случайное число между a и b в Ruby?

190

Например, чтобы сгенерировать случайное число от 3 до 10, я использую: rand(8) + 3

Есть ли способ сделать это лучше (что-то вроде rand(3, 10))?

Миша Морошко
источник
4
def my_rand(x, y); rand(y - x) + x; end
Тео
@ Тео y - x + 1, кстати.
Nakilon
1
Попробуйте ваш правильный ответ на 10 и 10 ** 24 в качестве пределов: 0 будет очень-очень долго ждать :)
Саян Малакшинов
5
Это работает:rand(3..10)
eikes

Ответы:

325

ОБНОВЛЕНИЕ: Ruby 1.9.3 Kernel#randтакже принимает диапазоны

rand(a..b)

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

Преобразование в массив может быть слишком дорогим и ненужным.


(a..b).to_a.sample

Или

[*a..b].sample

Массив # образец

Стандарт в Ruby 1.8.7+.
Примечание: в 1.8.7 был назван #choice, а в более поздних версиях был переименован.

Но в любом случае для создания массива требуются ресурсы, и решение, которое вы уже написали, является лучшим, что вы можете сделать.

Накилон
источник
Благодарность! Думаю, я останусь с старым и хорошим методом :)
Миша Морошко
32
Это действительно плохая идея, особенно если ваши a и b неизвестного размера. Попробуйте (100000000000000000..100000000000000) .to_a.sample и посмотрите, что я имею в виду
:)
4
@pixelearth, если у вас есть лучшее представление о том, что соответствует вопросу, вы можете оставить сообщение.
Nakilon
rand(a..b)не работает, она распадается: TypeError: can't convert Range into Integer. Это даже не поддерживается в Ruby 2.0
fguillen
2
@fguillen У меня работает в 1.9.3, я не знаю, почему у вас не работает.
Майкл Дорст
87
Random.new.rand(a..b) 

Где aваша самая низкая ценность и bваша самая высокая ценность.

user1782571
источник
4
Следует отметить важное различие: если вы просто звоните, rand()вы звоните Kernel#rand, что поддерживает только maxаргумент. Если вы хотите передать диапазон, вы должны использовать Random#rand, что означает, что вы должны реализовать этот способ. +1
grumpit
2
следует добавить, что вышесказанное относится к 1.9.2
grumpit
он включает a и b?
Abhradip
12
rand(3..10)

Ядро # rand

Когда max является Range, rand возвращает случайное число, где range.member? (Number) == true.

Дориан
источник
11

Обратите внимание на разницу между операторами диапазона:

3..10  # includes 10
3...10 # doesn't include 10
Янив Прейс
источник
3

Смотрите этот ответ: есть в Ruby 1.9.2, но нет в более ранних версиях. Лично я думаю, что rand (8) + 3 в порядке, но если вам интересно, посмотрите класс Random, описанный в ссылке.

бнаул
источник
3

Для 10 и 10 ** 24

rand(10**24-10)+10
Саян Малакшинов
источник
3
или простоrand(10..10**24)
Майкл Дорст
2

А вот быстрый тест для #sampleи #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)

Итак, делать rand(a..b)это правильно

Вадим Тёмиров
источник