繁体   English   中英

Ruby on Rails数组迭代

[英]Ruby on rails array iteration

我是Rails(和ruby)的新手。 遍历数组以累加变量的标准方法是什么?

例如,对于一个月的总费用,首先是一个数组:

expenses_this_month = expenses.find :all,
                                    :conditions => ['date >= ? and date <= ?',
                                      Date.today.beginning_of_month, Date.today.end_of_month]

我已经知道这样做的两种方式:

total = 0.0
for expense in expenses_this_month
  total += expense.cost
end
return total

或带块

total = 0.0
expenses_this_month.each do |expense|
  total += expense.cost
end
return total

我知道ruby方法的最后一行将默认返回,因此必须有更好的编写方法吗?

inject方法会很好用,就像Doug建议的那样。 但是,通常最好在可能的情况下在数据库中执行类似的操作。 ActiveRecord为此提供了一个简单的界面。

total = Expenses.sum :cost, :conditions => {
  :date => (Date.today.beginning_of_month..Date.today.end_of_month)
}

请注意,您还可以使用Range对象代替SQL插值。

如果由于其他原因要加载所有Expense对象,则注入方法当然可以。

您正在寻找Enumerable#inject方法:

expenses_this_month.inject(0.0) {|total, expense| total + expense }

此方法(从Smalltalk借用)采用传递给它的值(在这种情况下为0.0),并为此设置内部变量。 然后,它将使用该变量的值(作为total )和每个后续元素(作为expense )的值调用该块,并将变量设置为该块返回的值(在这种情况下,total和当前元素之和)。

但是,正如kejadlen所建议的那样,您可能希望通过使用#sum方法将此计算卸载到数据库中。

expenses_this_month.map(&:cost).sum

(较短,尽管它与reduce不同,但是在内存中创建了一个数组)

expenses_this_month.reduce(BigDecimal.new('0')) { |total, expense| total + expense.cost }

您需要记住传递一个初始值来减少(否则它将为空数组返回nil),并在处理货币时使用BigDecimal而不是常规浮点数。

返回数据后,请使用inject方法:

total = expenses_this_month.inject { |total, expense| total + expense.cost }

但是,您应该只重写查询:

total = expenses.sum(:cost, :conditions => ['date >= ? and date <= ?',
                                  Date.today.beginning_of_month, Date.today.end_of_month])

如果您使用的是Rails,则可以使用内置的sum类方法(假设Expense是类名)。

expenses_this_month = Expense.sum('cost', 
                                  :conditions => ['date >= ? and date <= ?',
                                                  Date.today.beginning_of_month,
                                                  Date.today.end_of_month])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM