2013-10-09 142 views
2

陣列我有一個數組,像這樣:["18:45", "18:45", "18:58"]的Rails:平均的時間

這裏是我使用的平均化時間的方法,包括:如果我運行

def avg_of_times(array_of_time) 
    size = array_of_time.size 
    avg_minutes = array_of_time.map do |x| 
     hour, minute = x.split(':') 
     total_minutes = hour.to_i * 60 + minute.to_i 
    end.inject(:+)/size 
    "%s:%s" % avg_minutes.divmod(60) 
    end 

同上述方法在irb控制檯,平均出來就好了,但在Rails中,它出現如下:18:148/3

什麼可能導致此方法在rails中無法正常工作?

Rails version: 3.2.14 
Ruby version: 1.9.3-p429 
+0

適合在'Rails 3.2.12','Ruby 1.9.3p448'中工作的我 –

+0

這太奇怪了,我無法讓它運行來拯救我的生命...如果我運行'3/4'在調試器控制檯它打印'(3/4)' – dennismonsewicz

+1

你有一個整數成爲一個理性(X/Y):3分之148= 49,33#=>如何表示的?你可以試試'avg_minutes.divmod(60).map(&:to_i)'? - 兼對我的作品的Ruby 1.9.3p448 && Rails的3.2.11 – MrYoshiji

回答

2

你的代碼在我的IRB控制檯,Rails 3.2.11Ruby 1.9.3-p448


的問題是,你得到你的計算浮點數,而這一次變成了理性的對象(解決無盡的0.33小數)。我想試試這個:

def avg_of_times(array_of_time) 
    size = array_of_time.size 
    avg_minutes = array_of_time.map do |x| 
    hour, minute = x.split(':') 
    total_minutes = hour.to_i * 60 + minute.to_i 
    end.inject(:+)/size 
    "%s:%s" % avg_minutes.divmod(60).map(&:to_i) 
            #^^^^^^^^^^^ here is the new part 
end 

或者像@馬特建議,只是四捨五入分鐘總量可以解決您的問題:

"%s:%s" % avg_minutes.round.divmod(60) 
1

問題不在軌道本身。可能是一些圖書館(可能是mathn)重新定義/使用Rational或類似這樣的東西。有描述some workaround以避免問題。

+0

我們使用'紅寶石units'寶石......難怪如果那是什麼導致它 – dennismonsewicz

+1

@dennismonsewicz爲您的評論在一個理性的對象3說:「3/4結果/ 4在你的控制檯中「,在我的控制檯3/4返回0(3.0/4返回0.75) - >所以我會說是的,你的寶石紅寶石單元有可能造成這種情況(將Floats into Rationals) – MrYoshiji

1

我相信你的問題已經有了答案。這裏有一個替代方法:

#require 'active_support' 

    a = ["18:35", "19:07", "23:09"] 
    avg = a.inject {|tot, str| tot + Time.parse(str).seconds_since_midnight}/(a.size.to_f).round 
    mins = avg.divmod(60).first 
    hours = mins.divmod(60).first 
    hours.to_s + ':' + (mins-hours*60).to_s # => "20:17" 
1

"%d:%02d" % avg_minutes.divmod(60)

這有兩個好處:

  • 它的工作原理,當avg_minutes是Rational對象。
  • 它格式化分鐘以兩位數字。所以你得到「18:01」而不是「18:1」。