1

我正在尝试重构一个写得很糟糕的方法。该方法旨在扫描包含如下所示的余额哈希的数组:

{ 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

但必须有一种更时尚的方式来做到这一点。我怎样才能重构这个方法,让它循环一次原始数组,而不是创建新数组并循环遍历它们?

4

1 回答 1

1

这是很好的代码。变量名很好,意图很明显。

遍历数组两次并没有错。Ruby 更多的是让你的意图清晰,而不是尽可能快的代码。你应该只在已知代码不够快时进行优化,然后你应该测量,以确保你实际上让它更快。当你做一些你认为会让它更快的事情时,Ruby 经常会因为变慢而让你吃惊。

第二个循环(将 balance 转换为 balance.amount)可以短接为:

balances_amounts = balances_for_month.map(&:amount)

总和可以缩短为:

balance_amounts.inject(&:+)

请参阅to_proc 方法是什么意思?了解这些是如何工作的。

有时临时代码会增加代码的清晰度;有时不是。一旦您使用了上述技术,就可以摆脱临时人员,留下:

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

起初这可能看起来有点密集,但一旦熟悉这些成语就会变得清晰。

于 2013-10-14T02:49:29.567 回答