2017-01-23 51 views
0

我試圖把2行的代碼紅寶石成1。例如:產生一個修改的Ruby陣列塊

def average(numbers) 
    result = numbers.compact 
    numbers.reduce(+)/numbers.length 
end 

我一直期待通過陣列方法,並不能找到一個適當的一個把這個功能變成一個單線程。我希望像這樣的工作:

def average(numbers) 
    numbers.compact.<tap or another method> { |arr| arr.reduce(+)/arr.length } 
end 

基本上,我修改陣列(在我打電話緊湊擺脫nil值的例子),所以我沒有訪問數組變量,我不想要迭代器,因爲我不想在數組的各個元素上調用reduce(+)length

有沒有人有我可以看到的方法的想法?

回答

2

我相信你的意思是你的方法是以下(reduce(:+),不reduce(+)並在第二行中使用result而非numbers)。

def average(numbers) 
    result = numbers.compact 
    result.reduce(:+)/result.length 
end 

average [1,2,3] 
    #=> 2 

如果您希望平均是一個浮動,第二行改爲

result.reduce(0.0, :+)/result.length 

有各種方式方法的兩行合併,但我不喜歡任何的他們到了上面。這裏有一些。 (我看不出Object#tap可以在這裏使用。)

numbers.compact.reduce(:+)/numbers.compact.length 

(result = numbers.compact).reduce(:+)/result.compact.length 

numbers.map(&:to_i).reduce(:+)/numbers.compact.length 

需要注意的是,即使numbers可以突變,一個不能寫

numbers.compact!.reduce(:+)/numbers.length 

因爲numbers.compact!回報nil如果numbers不含nil元素。

在Ruby V2.4 +你可以使用Array#sum

result.sum/result.length 
+0

很酷,我剛剛和我的一位隊友交談過,我們同意我的觀點(包括更正內容)最適合可讀性。 –

+0

儘管我在這裏學到了一些東西:'(result = numbers.compact).reduce(:+)/ result.compact.length'謝謝! –

+1

感謝您的更正,@Stefan。我的意思是將平均值的計算結果寫爲'result.reduce(:+)。to_f/result.length',但我更喜歡你做它的方式。 –

0

你可以改變你的方式調用average

def average(numbers) 
    numbers.reduce(:+)/numbers.length 
end 

average(num_array.compact) 
+0

謝謝。無論如何,我認爲我已經脫離了雜草「我無法訪問數組變量」部分。 – seph

+0

謝謝@seph –