2013-01-31 31 views
5

在下面的Ruby代碼紅寶石#detect行爲我有根據的d100結果包含在ary兩種方法d100_in_detectd100_out_detect其中(爲簡單起見數字)返回唯一元素的Array利用隨機數

def d100 
    1 + (rand 100) 
end 

def d100_in_detect(ary) 
    choice = [ ] 
    100.times do 
    choice.push ary.detect { |el| d100 <= el } 
    end 
    choice.uniq.sort 
end 

def d100_out_detect(ary) 
    choice = [ ] 
    numbers = [ ] 

    100.times do 
    numbers.push d100 
    end 

    numbers.each do |i| 
    choice.push ary.detect { |el| i <= el } 
    end 

    choice.uniq.sort 
end 

正如你可以看到這兩種方法之間的差別在於,在所述第一d100稱爲detect的塊內,而在第二個100個隨機號碼存儲在numbers陣列,然後被用作它發生在d100_in_detect

讓我們假設我所說的兩個方法如下

ary = [ ] 
50.times do |i| 
    ary.push i * 5 
end 

puts '# IN DETECT #' 
print d100_in_detect ary 
puts 

puts '# OUT DETECT #' 
puts d100_out_detect ary 
puts 

一個典型的輸出如下。

# IN DETECT # 
[ 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55 ] 
# OUT DETECT # 
[ 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100 ] 

我找不出爲什麼這兩個方法返回這種不同的結果。 在detect的區塊中調用d100方法是否有任何含義?

回答

2

沒錯。

我所做的第一件事就是修改腳本示例:

def d100_in_detect(ary) 
    choice = [ ] 
    numbers = [] 
    100.times do 
    var = d100 
    numbers << var 
    choice.push ary.detect { |el| var <= el } 
    end 
    puts numbers.inspect 
    choice.uniq.sort 
end 

def d100_out_detect(ary) 
    choice = [ ] 
    numbers = [ ] 

    100.times do 
    numbers.push d100 
    end 
    puts numbers.inspect 

    numbers.each do |i| 
    choice.push ary.detect { |el| i <= el } 
    end 

    choice.uniq.sort 
end 

正如你看到的,我所做的是D100的結果分配給一個臨時變量,看看發生了什麼事....而'錯誤'消失了!我的返回值突然相同。嗯。

然後,我想起了究竟發生了什麼。當你「緩存」變量時(就像你在第二個例子中那樣),你保證你有100個數字。

當您遍歷塊時,對於塊中的每個數字,您再次執行d100。因此,第一個有更多的呼叫比第二個呼叫多 ...但您還需要在該號碼被調用時隨機生成的號碼大於號碼(而如果您隨機生成100與2,你可以保證它會在某個時候達到100)。這極大地偏向於您的腳本朝向較低的數字!

舉一個例子,運行:

@called_count = 0 
def d100 
    @called_count += 1 
    1 + (rand 100) 
end 

def d100_in_detect(ary) 
    choice = [ ] 
    numbers = [] 
    100.times do 
    choice.push ary.detect { |el| d100 <= el } 
    end 
    puts @called_count.inspect 
    @called_count = 0 
    choice.uniq.sort 
end 

def d100_out_detect(ary) 
    choice = [ ] 
    numbers = [ ] 

    100.times do 
    numbers.push d100 
    end 
     puts @called_count.inspect 
    @called_count = 0 

    numbers.each do |i| 
    choice.push ary.detect { |el| i <= el } 
    end 

    choice.uniq.sort 
end 

我得到

# IN DETECT # 
691 
# OUT DETECT # 
100 
+0

感謝在塊_each號,您執行D100 again_。 – dave

+0

是的,這真的是它的關鍵。我放下了其餘的部分,因爲我必須運行並使用腳本來了解發生了什麼。感謝您提供這樣一個詳細的問題! –