2013-04-09 79 views
0

我一直在研究一些項目歐拉問題,以幫助學習編程,並想知道如果有人能解釋這一點給我。紅寶石!地圖不改變對象類型

我有一串數字,我試圖找到序列中任意五個最大的產品。這是我到目前爲止有:

temp = series.split(//).map!{|x| x.to_i} 
len = temp.length 
maxprod = 1 
0.upto(len-4) do |x| 
    num = (temp[x] * temp[x+1] * temp[x +2] * temp[x+3] * temp[x+4]) 

    if num > maxprod 
     maxprod = num 
    end 

end 

puts maxprod 

溫度[0]的.class返回一個Fixnum,但是,當我運行的代碼我得到一個錯誤「*:無不能強迫Fixnum對象(類型錯誤)」

由於

回答

4

這是因爲map返回一個數組。 map!返回nil。然後,您正在服用的是nilmap!回報,並把它變成temp

他們兩個仍然運行split結果中的每個元素塊,但你應該總是使用map當你想要的結果被放入一個變量。這是一個微妙的事情,可以輕鬆地把你絆倒。

變化

temp = series.split(//).map!{|x| x.to_i} 

temp = series.split(//).map{|x| x.to_i} 

獎勵:

您可以使用符號&和方法爲標誌的名稱爲塊傳遞到map

temp = series.split(//).map(&:to_i) 

編輯:

根據您的意見,乘以數組中的元素時,你仍然得到錯誤。這可能是因爲您的temp陣列沒有您認爲的那樣多的元素。嘗試使用索引訪問數組目前沒有任何內容,將導致nil

temp = [1] 
temp[0] #=> 1 
temp[1] #=> nil 
temp[0] * temp[1] #=> TypeError: nil can't be coerced into FixNum 

您提到使用temp[1].to_i修復了此問題。這是因爲nil可以轉換爲整數。

nil.to_i #=> 0 

我會檢查temp的結果以確保它包含您認爲它包含的內容。 你可能也想看看Enumerable#each_slice,它需要一個數組的子集並在一個塊中處理它。

nums = %w{08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08}.map(&:to_i) 
nums.each_slice(4) {|a| puts a.inject(:*)} 
+1

爲了擴展這一點,ruby範例是破壞性方法(改變對象內部狀態的方法)往往有一個!後綴。在你的情況下,地圖!指示它修改您引用的任何可枚舉對象的內部結構,而map則會從原始對象創建一個新的已更改對象並將其返回。 – mcfinnigan 2013-04-09 16:08:03

+0

我做了更改,但仍然收到相同的錯誤。我沒有改變循環爲「temp [x] .to_i * temp [x + 1] .to_i ...」,這似乎工作(似乎重複)。 – MattLock 2013-04-09 16:12:03

+0

這可能是因爲'temp'沒有包含你認爲的那麼多元素。請注意,如果一個數組只有1個元素,'temp [1] == nil'。因此,'temp = [1]; temp [0] * temp [1]'會給你你得到的錯誤。 'to_i'爲你工作的原因是因爲'nil.to_i == 0' – 2013-04-09 16:49:13