簡體   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