Ruby,时间差一阵子

时间:2011-09-27 00:00:31

标签: ruby-on-rails ruby

我有一个查询(对于一个MongoDB数据库),它返回已经mapreduced的对象,每15分钟报告一次对象,但问题是如果说我们在其中一个服务器中有一个严重错误,那段时间将是下落不明。

以此数组为例:

[
  {:timestamp=>2011-09-26 19:00:00 UTC, :count=>318},
  {:timestamp=>2011-09-26 19:15:00 UTC, :count=>308},
  {:timestamp=>2011-09-26 19:30:00 UTC, :count=>222},
  {:timestamp=>2011-09-26 19:45:00 UTC, :count=>215},
  {:timestamp=>2011-09-26 20:00:00 UTC, :count=>166},
  {:timestamp=>2011-09-26 21:15:00 UTC, :count=>149},
  {:timestamp=>2011-09-26 21:30:00 UTC, :count=>145},
  {:timestamp=>2011-09-26 21:45:00 UTC, :count=>107},
  {:timestamp=>2011-09-26 22:00:00 UTC, :count=>137},
  {:timestamp=>2011-09-26 22:15:00 UTC, :count=>135},
  {:timestamp=>2011-09-26 22:30:00 UTC, :count=>191},
  {:timestamp=>2011-09-26 22:45:00 UTC, :count=>235}
]

您会注意到时间范围内缺少时间:

{:timestamp=>2011-09-26 20:15:00 UTC},
{:timestamp=>2011-09-26 20:30:00 UTC},
{:timestamp=>2011-09-26 20:45:00 UTC},
{:timestamp=>2011-09-26 21:00:00 UTC}

如何将顶部作为输入并推断出那些将是缺失的行?时间增量总是15分钟,它实际上是一个真实的日期对象,而不是像这样的字符串。

我无法想象如何迭代这个。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

我能想到的最简单的方法是按时间戳排序数组,然后执行以下操作:

missing_times = []
reports.each_with_index do |report, index|
  if reports[index + 1]
    if report.timestamp.advance(minutes: 15) < report[index + 1].timestamp
      i = 0
      while(report.timestamp.advance(minutes: 15*i) < report[index+1].timestamp)
        missing_times << report.timestamp.advance(minutes: 15*i)
      end
    end
  end
end

我之前写过类似的代码,可以在一系列约会中找到半小时的差距

虽然看起来我的解决方案会在reports.first和reports.last之间以15分钟为增量循环多次,但它实际上只会在reports.first和reports.last

之间的所有可用增量上循环一次。

答案 1 :(得分:1)

如果您以15分钟为增量创建总时间跨度的数组,并且只是与报告集进行比较并删除任何匹配项,而不是在循环内执行多个循环,对于大型数据集会更有效。

start_time = report.first
span = ((report.last - start_time)/60/15).to_i   # this gives the number of 15min blocks
test_array = []
span.times do |i|
  test_array << start_time + i*15.minutes
end
report.each do |r|
  test_array.delete(r)   # or in your case, r.timestamp
end

我认为它有效,但想不出一个制作时间戳参考表的好方法,所以我在那里破解了。

答案 2 :(得分:0)

只需从第一个时间戳开始,然后递增15分钟,验证该条目是否存在,并继续前进,直至到达上一个时间戳。