[英]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.