我试图重构一个写得很差的方法。该方法用于扫描包含如下所示的平衡散列的数组:
{ 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但一定有更好的方法。我如何重新构造这个方法,使它一次遍历原始数组,而不是创建新的数组并循环它们?
发布于 2013-10-14 02:49:29
这是很好的密码。变量名是好的,意图是显而易见的。
两次遍历数组没有什么问题。Ruby更多的是让您的意图变得更清晰,而不是关于最快的代码。只有当已知的代码不够快时,您才应该进行优化,然后您应该进行度量,以确保您实际上正在使它变得更快。当您做一些您认为会使它更快的事情时,Ruby常常会让您感到惊讶。
第二个循环(将平衡转换为balance.amount)可以缩短为:
balances_amounts = balances_for_month.map(&:amount)这笔款项可缩短为:
balance_amounts.inject(&:+)有关这些操作的说明,请参见proc method mean?。
有时临时人员会增加代码的清晰度;有时则不会。一旦您使用了上述技术,临时人员就可以摆脱,离开:
balances.select do |balance|
balance.month_end == month
end.map(&:amount).inject(&:+)乍一看,这似乎有点稠密,但一旦熟悉了这些成语,就会变得清晰起来。
https://stackoverflow.com/questions/19352702
复制相似问题