Array#sample
如果將範圍作爲隨機數生成器傳遞,Array#sample
如何工作? 如這裏:Array#示例隨機數生成器
> [*1..10].sample(random: 1..3)
=>9
Array#sample
如果將範圍作爲隨機數生成器傳遞,Array#sample
如何工作? 如這裏:Array#示例隨機數生成器
> [*1..10].sample(random: 1..3)
=>9
按照商務部,,rng
不是Range
對象,因爲你可能會想。 rng
是隨機號碼發生器。
The optional rng argument will be used as the random number generator.
a = (1..10).to_a
r = Random.new
r2 = r.dup
a1 = a.sample(random: r)
a2 = a.sample(random: r2)
a1 == a2 # => true
點是#sample
,取其秒參數作爲關鍵字參數。如果我們使用類似foo: 12
或rng: (1..2)
的東西,它會給ArgumentError:未知關鍵字:。 可選參數只有在您提供值爲random: <any random number generator>
時纔可接受。現在,來到你的觀點:
r = 1..3
a1 = [*1..10].sample(random: r)
a2 = [*1..10].sample(random: r)
a1 == a2 # => false
你逝去的第二個參數爲random: r
,r
必須Random
對象或對象來響應#rand
。請記住第二個的說法,你告訴#sample
,使用你的隨機數發生器而不是默認它在沒有可選參數的情況下使用。
這裏是一個定製實施RNG的:
ob = Object.new
def ob.to_int
5000
end
gen_to_int = proc do |max|
ob
end
class << gen_to_int
alias rand call
end
ary = (0...10000).to_a
ary.sample(random: gen_to_int) # => 5000
ary.sample(random: gen_to_int) # => 5000
ary.sample(random: gen_to_int) # => 5000
這會給你的理解與可選參數約#sample
。從#test_sample_random
中查找更多示例。
更新
How does
Array#sample
work, if you pass a range as random numbers generator?
要回答這個問題,我想借此TracePoint
類的幫助。
trace = TracePoint.new(:c_call) do |tp|
p [tp.lineno, tp.defined_class, tp.method_id, tp.event]
end
trace.enable do
[1,2,3,4,5,66,4].sample(random: 1..3)
end
# >> [6, Array, :sample, :c_call]
# >> [6, Kernel, :rand, :c_call]
# >> [6, Kernel, :respond_to_missing?, :c_call]
所以,從上面的調用堆棧,你可以看到 - Array#sample
方法被調用。現在在內部,Ruby在Range
對象上調用Kernel#rand
。現在,(1..3).respond_to?
返回false
(因爲#rand
- 它是Range
的a_private_實例方法),這就是爲什麼最終#respond_to_missing?
方法已被調用來完成這項工作。
所以這個方法檢查'sample(random:rng)'中的'rng'是否實際上是一個隨機數生成器?你能解釋一下嗎? – zerozero7 2015-02-23 19:47:50
@ zerozero7如何表示?我給你的例子..仍然不服氣.. :-) – 2015-02-23 19:49:20
如何 - 在條款如何知道,提供的價值確實是一個隨機數發生器,而不是範圍對象,例如。我理解你的例子,我不是故意粗魯。只是好奇該方法實際上是否省略了可選參數。 – zerozero7 2015-02-23 19:58:20