Làm cách nào để tạo một số ngẫu nhiên giữa a và b trong Ruby?


189

Ví dụ, để tạo một số ngẫu nhiên từ 3 đến 10, tôi sử dụng: rand(8) + 3

Có cách nào đẹp hơn để làm điều này (một cái gì đó như rand(3, 10))?


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

@Theo, y - x + 1nhân tiện.
Nakilon

1
Hãy thử câu trả lời đúng của bạn vào ngày 10 và 10 ** 24 vì các giới hạn: 0 sẽ rất rất chờ đợi :)
xt.and.r

5
Điều này hoạt động:rand(3..10)
eike

Câu trả lời:


323

CẬP NHẬT: Ruby 1.9.3 Kernel#randcũng chấp nhận phạm vi

rand(a..b)

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

Chuyển đổi sang mảng có thể quá tốn kém và không cần thiết.


(a..b).to_a.sample

Hoặc là

[*a..b].sample

Mảng # mẫu

Tiêu chuẩn trong Ruby 1.8.7+.
Lưu ý: được đặt tên #choice trong 1.8.7 và được đổi tên trong các phiên bản sau.

Nhưng dù sao, việc tạo mảng cần tài nguyên và giải pháp bạn đã viết là tốt nhất, bạn có thể làm.


Cảm ơn! Tôi nghĩ rằng tôi sẽ ở lại với phương pháp cũ và tốt :)
Misha Moroshko

32
Đây là một ý tưởng thực sự tồi tệ, đặc biệt nếu a và b của bạn có kích thước không xác định. Hãy thử (100000000000000000..100000000000000) .to_a.sample và xem ý tôi là gì :)
pixelearth

4
@pixelearth, nếu bạn có ý tưởng tốt hơn, phù hợp với câu hỏi, bạn có thể đăng bài.
Nakilon

rand(a..b)không hoạt động, nó chia tách : TypeError: can't convert Range into Integer. Nó thậm chí không được hỗ trợ trong Ruby 2.0
fguillen

2
@fguillen Nó hoạt động với tôi trong 1.9.3, tôi không biết tại sao nó không hiệu quả với bạn.
Michael Dorst

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

aGiá trị thấp nhất của bạn ở đâu và blà giá trị cao nhất của bạn.


4
Sự khác biệt quan trọng cần lưu ý là nếu bạn chỉ gọi rand()bạn đang gọi Kernel#rand, điều này chỉ hỗ trợ một maxđối số. Nếu bạn muốn vượt qua một phạm vi, bạn phải sử dụng Random#rand, có nghĩa là bạn phải thực hiện theo cách này. +1
gắt gỏng

2
nên thêm rằng những điều trên áp dụng cho 1.9.2
grumpit

nó có bao gồm a và b không?
Abhradip


11

Chỉ cần lưu ý sự khác biệt giữa các toán tử phạm vi:

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

3

Xem câu trả lời này : có trong Ruby 1.9.2, nhưng không có trong các phiên bản trước. Cá nhân tôi nghĩ rằng rand (8) + 3 là tốt, nhưng nếu bạn quan tâm hãy xem lớp Ngẫu nhiên được mô tả trong liên kết.




2

Và đây là một điểm chuẩn nhanh cho cả hai #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)

Vì vậy, làm rand(a..b)là điều đúng đắn

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.