【问题标题】:Average array of times as strings in RubyRuby中字符串的平均时间数组
【发布时间】:2013-12-11 23:37:33
【问题描述】:

我有一个数组:

array = ["0:00:31", "0:00:52", "0:01:05", "0:00:55", "0:01:33", "0:00:05", "0:00:01", 
      "0:05:10", "0:02:40", "0:03:03", "0:01:33", "0:00:00"]

我需要对数组中不等于"0:00:00" 的所有时间进行平均。 "0:00:00" 应该被扔掉。

最好的方法是什么?我目前正在遍历数组,删除所有 0:00:00 值,将字符串转换为整数并进行平均 - 但对于我正在尝试做的事情来说,这似乎有很多代码。

【问题讨论】:

标签: ruby arrays time average


【解决方案1】:
(sz = array.reject    {|t| t == '0:00:00' }).
            map       {|t| Time.parse t   }.
            reduce(0) {|a, t| a += t.to_i }.to_f / sz.size

您希望将这些东西分组到功能操作中。拒绝你不需要的东西,然后对其余的采取行动。

这里,reduce 是获取数组平均值的可行方法,and has been answered before.


这里有一个更简洁、更神秘的替代方案

(sz = array.reject {|t| t == '0:00:00'     }).
            map    {|t| Time.parse(t).to_i }.
            reduce(:+).to_f / sz.size

【讨论】:

  • 添加和解析时间就像一个 rails 的东西,我无法让它在纯 Ruby 中工作。
  • array.size 将返回包含零的数组的大小。你可以使用.sum,而不是reduce(:+)
  • Ruby 总是令人惊叹。感谢您的提示和一些新方法的介绍。
【解决方案2】:

调整 NewAlexandria 的答案,以秒为单位返回平均值:

(sz = array.reject    {|t| t == '0:00:00' }).
            map       {|t| t.split(":").inject(0){|product,n| product * 60 + n.to_i} }.
            reduce(0) {|a, t| a += t.to_i }.to_f / sz.size

【讨论】:

  • 它们是相同的结果,是的,除了你的 float return val
【解决方案3】:

由于某种原因,我没有得到 NewAlexandria 的答案,我会这样做:

def average_of_times(array)
    zero_seconds      = ->x{ x=='0:00:00' }
    covert_to_seconds = ->x do
      hours, minutes, seconds = x.split(':').map(&:to_i)
      hours * 3600 + minutes * 60 + seconds
    end

    seconds = array.reject!(&zero_seconds)
             .map(&covert_to_seconds)
             .reduce(:+) / array.size

    Time.at(seconds).utc.strftime("%H:%M:%S")
end

【讨论】:

    猜你喜欢
    • 2021-09-15
    • 2011-12-10
    • 2015-10-15
    • 1970-01-01
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    • 2012-07-18
    • 1970-01-01
    相关资源
    最近更新 更多