2013-10-14 43 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(&:+) 

这初看起来似乎有点晦涩难懂,但变得清晰,一旦一个熟悉这些成语。