2013-10-14 74 views
1

我試圖重構一個寫得很差的方法。該方法是指掃描陣列包含平衡哈希看起來像這樣:如何簡化累計每月餘額的enum-ridden方法

{ amount: $123, month_end: '2013-01-31' } 

,並與當月最後返回所有的餘額,然後總結出的數額。

def monthly_total(month) 
    balances = [ balance_1, balance_2 ] 
    # get and array of balances 
    balances_for_month = balances.select do |balance| 
    balance.month_end == month 
    end 
    # grab only the balances for the desired month 
    balance_amounts = balances_for_month.map do |balance| 
    balance.amount 
    end 
    #take all the balances for the month and sum them. 
    balance_amounts.inject{|sum,x| sum + x } 
end 

但是有一個更光滑的方法來做到這一點。我怎樣才能重構這個方法,以便它在原始數組上循環一次,而不是創建新的數組並循環遍歷它們?

回答

1

這是很好的代碼。變量名稱很好,意圖很明顯。

兩次通過數組沒有任何問題。 Ruby更關心的是讓你的意圖清楚,而不是關於儘可能快的代碼。只有在知道代碼速度不夠快時,才應該進行優化,然後應該進行測量,以確保實際上能夠加快速度。當你做一些你認爲會加快速度的事情時,Ruby會讓你感到驚訝。

第二環路(變換成平衡balance.amount)可以短於:

balances_amounts = balances_for_month.map(&:amount) 

總和可以縮短爲:

balance_amounts.inject(&:+) 

如何這些工作的說明見What does to_proc method mean?

有時候臨時性會增加代碼的清晰度;有時不。一旦你使用上述技術的臨時工可以擺脫了,留下:

balances.select do |balance| 
    balance.month_end == month 
end.map(&:amount).inject(&:+) 

這初看起來似乎有點晦澀難懂,但變得清晰,一旦一個熟悉這些成語。