2015-12-08 25 views
1

我想從一個散列數組中計算平均時間。這是數組。從散列數組計算平均時間

array = [ 
    {"startTime"=>"2015-12-05T07:49:30.000Z", "endTime"=>"2015-12-05T15:56:30.000Z"}, 
    {"startTime"=>"2015-12-04T07:02:30.000Z", "endTime"=>"2015-12-04T14:59:30.000Z"}, 
    {"id"=>"5660614e8a3b090700bad845", "userId"=>"55cd59542d98600100397c12", "day"=>"2015-12-03", "startTime"=>"2015-12-03T06:02:32.000Z", "endTime"=>"2015-12-03T13:38:32.000Z"}, 
    {"startTime"=>"2015-12-02T09:17:33.000Z", "endTime"=>"2015-12-02T15:27:33.000Z"}, 
    {"startTime"=>"2015-12-01T05:45:36.000Z", "endTime"=>"2015-12-01T13:50:36.000Z"} 
] 

我想獲得平均startTime和endTime。這是我到目前爲止所嘗試過的。

avg = Time.at(array.map {|x| x['startTime']}.reduce(:+).to_f/array.size.to_i) 

我得到的結果是1969-12-31 16:06:43 -0800。這是不正確的。

回答

4
require 'time' 

array = [ 
    {"startTime"=>"2015-12-05T07:49:30.000Z", "endTime"=>"2015-12-05T15:56:30.000Z"}, 
    {"startTime"=>"2015-12-04T07:02:30.000Z", "endTime"=>"2015-12-04T14:59:30.000Z"}, 
    {"id"=>"5660614e8a3b090700bad845", "userId"=>"55cd59542d98600100397c12", "day"=>"2015-12-03", "startTime"=>"2015-12-03T06:02:32.000Z", "endTime"=>"2015-12-03T13:38:32.000Z"}, 
    {"startTime"=>"2015-12-02T09:17:33.000Z", "endTime"=>"2015-12-02T15:27:33.000Z"}, 
    {"startTime"=>"2015-12-01T05:45:36.000Z", "endTime"=>"2015-12-01T13:50:36.000Z"} 
] 

times = array.map{|el| el['startTime']}.map{|el| Time.parse(el) } 
#=> [2015-12-05 07:49:30 UTC, 2015-12-04 07:02:30 UTC, 2015-12-03 06:02:32 UTC, 2015-12-02 09:17:33 UTC, 2015-12-01 05:45:36 UTC] 

average_time = Time.at(times.map(&:to_f).inject(:+)/times.size) 
#=> 2015-12-03 08:11:32 +0100 
+0

' el'應該已經是一個字符串了,所以我不認爲你需要調用'#to_s'。 –

+0

@MichaelStalker對,編輯答案,thx! :) –

+0

出於某種原因,我沒有得到這個數組的正確的平均時間。 times = [2015-12-10 05:58:24 UTC, 2015-12-09 03:35:28 UTC, 2015-12-08 06:32:26 UTC, 2015-12-07 01 :43:28 UTC, 2015-12-05 07:49:30 UTC, 2015-12-04 07:02:30 UTC] ave = Time.at(bed_times.map(&:to_f).inject (:+)/ bed_times.size) 2015-12-07 01:26:57 -0800 這不是正確的平均時間。另外,我將如何將其轉換爲不同的時區? – user2974739

1
require 'time' 

keys = ["startTime", "endTime"] 
n = array.size 
keys.zip(array.map { |h| h.values_at(*keys).map { |d| Time.parse(d).to_f }}. 
    transpose. 
    map { |a| Time.at(a.reduce(:+)/n) }).to_h 
    #=> {"startTime"=>2015-12-02 23:11:32 -0800, "endTime"=>2015-12-03 06:46:32 -0800} 

的步驟:

keys = ["startTime", "endTime"] 
n = array.size 
    #=> 5 
a = array.map { |h| h.values_at(*keys).map { |d| DateTime.parse(d).to_time.to_f }} 
    #=> [[1449301770.0, 1449330990.0], 
    # [1449212550.0, 1449241170.0], 
    # [1449122552.0, 1449149912.0], 
    # [1449047853.0, 1449070053.0], 
    # [1448948736.0, 1448977836.0]] 

在計算a,塊變量初始設置爲的array第一個元素:

h = array.first 
    #=> {"startTime"=>"2015-12-05T07:49:30.000Z", "endTime"=>"2015-12-05T15:56:30.000Z"}  

和塊執行計算:

b = h.values_at(*keys)  
    #=> ["2015-12-05T07:49:30.000Z", "2015-12-05T15:56:30.000Z"] 
b.map { |d| Time.parse(d).to_f } 
    #=> [1449301770.0, 1449330990.0] 

a的其他元素的計算方法相似。

與計算繼續:

c = a.transpose 
    #=> [[1449301770.0, 1449212550.0, 1449122552.0, 1449047853.0, 1448948736.0], 
    # [1449330990.0, 1449241170.0, 1449149912.0, 1449070053.0, 1448977836.0]] 

d = c.map { |a| Time.at(a.reduce(:+)/n) } 
    #=> [2015-12-02 23:11:32 -0800, 2015-12-03 06:46:32 -0800] 

d的計算等同於:

e = c.map { |a| a.reduce(:+) } 
    #=> [7245633461.0, 7245769961.0] 
f = e.map { |t| t/n } 
    #=> [1449126692.2, 1449153992.2] 
d = f.map { |t| Time.at(t) } 
    #=> [2015-12-02 23:11:32 -0800, 2015-12-03 06:46:32 -0800] 

的最後一步是呈現結果在哈希:

g = keys.zip(d) 
    #=> [["startTime", 2015-12-02 23:11:32 -0800], ["endTime", 2015-12-03 06:46:32 -0800]] 
g.to_h 
    #=> {"startTime"=>2015-12-02 23:11:32 -0800, 
    # "endTime"=>2015-12-03 06:46:32 -0800}