【问题标题】:Ruby: Average array of timesRuby:平均次数
【发布时间】:2013-10-09 18:51:07
【问题描述】:

我的Array 类中有以下方法:

class Array
  def avg
    if partial_include?(":")
      avg_times
    else
      blank? and 0.0 or (sum.to_f/size).round(2)
    end
  end

  def avg_times
    avg_minutes = self.map do |x|
      hour, minute = x.split(':')
      total_minutes = hour.to_i * 60 + minute.to_i
    end.inject(:+)/size
    "#{avg_minutes/60}:#{avg_minutes%60}"
  end

  def partial_include?(search_term)
    self.each do |e|
      return true if e[search_term]
    end
    return false
  end
end

这对常规数字数组非常有效,但在某些情况下我可能有一个时间数组。

例如:[18:35, 19:07, 23:09]

要算出时间对象数组的平均值吗?

【问题讨论】:

  • 该格式的字符串还是日期时间对象?
  • 您可以致电to_i 并获得总和和除数。如果你先减去一个偏移量会更快,这样你就不用Bignums
  • 它们是否曾经混合过,或者总是数字或时间,从不两者兼而有之?
  • @hirolau - 它们是字符串
  • 现在的代码可以用 self.first[':'] 替换 partial_include?(":") 然后删除 partial_include?方法。

标签: ruby-on-rails ruby arrays


【解决方案1】:

所以你需要定义一个函数来计算格式化为字符串的时间平均值。将数据转换为分钟,平均总分钟数,然后返回时间。

我会这样做:

a =  ['18:35', '19:07', '23:09']

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
  "#{avg_minutes/60}:#{avg_minutes%60}"
end

p avg_of_times(a) # = > "20:17"

然后,当您调用函数时,您会检查数组中的任何/所有项目是否被格式化为时间。也许使用正则表达式。

【讨论】:

  • 当我运行它时,我转储的值为“847/45:148/3”——我用我的 Array 类的新版本更新了我的问题
  • 这对我来说适用于最新版本的 Ruby。如果你跳过最后一行,你得到正确的分钟数吗? (在我上面的例子中是 1217?)如果是这样,只需编写您自己的“将分钟转换为小时和分钟”行。
  • 嗯...是的,我正在运行 ruby​​ 1.9.3
  • 把最后一行改成 "%s:%s" % avg_minutes.divmod(60) ruby-doc.org/core-1.9.3/Numeric.html#method-i-divmod
  • 谢谢!这就像一个魅力!奇怪的是我有另一个开发人员正在运行 Ruby 1.9.3-p329 并且它按预期工作
【解决方案2】:

分别平均小时和分钟

这是我们正在使用的一个简单方法:

def calculate_average_of_times( times )
  hours   = times.collect{ |time| time.split( ":" ).first.to_i }  # Large Arrays should only
  minutes = times.collect{ |time| time.split( ":" ).second.to_i } # call .split 1 time.

  average_hours   = hours.sum / hours.size
  average_minutes = ( minutes.sum / minutes.size ).to_s.rjust( 2, '0' ) # Pad with leading zero if necessary.

  "#{ average_hours }:#{ average_minutes }"
end

并显示它与您提供的 Array 的 24 小时时间一起使用,转换为 Strings

calculate_average_of_times( ["18:35", "19:07", "23:09"] )
#=> "20:17"

感谢 @matt-privman 在这方面的帮助和启发。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-21
    • 2011-12-10
    • 2017-05-19
    • 1970-01-01
    • 2013-12-11
    • 1970-01-01
    相关资源
    最近更新 更多