【问题标题】:Calculate average time from array of hashes从哈希数组计算平均时间
【发布时间】:2024-01-21 03:18:01
【问题描述】:

我正在尝试从哈希数组中计算平均时间。这是数组。

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。这是不正确的。

【问题讨论】:

    标签: arrays ruby datetime hash average


    【解决方案1】:
    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
    

    【讨论】:

    • el 应该已经是一个字符串了,所以我认为你不需要调用#to_s 就可以了。
    • 由于某种原因,我没有得到这个数组的正确平均时间。时间 = [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 为什么不是?我认为 04 到 10 之间的平均值是 07。所以我认为它是正确的 avg。
    【解决方案2】:
    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时,block变量初始设置为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} 
    

    【讨论】: