当前位置:  开发笔记 > 后端 > 正文

使用delta迭代Ruby Time对象

如何解决《使用delta迭代RubyTime对象》经验,为你挑选了3个好方法。

有没有办法迭代Ruby中的时间范围,并设置delta?

这是我想要做的事情的想法:

for hour in (start_time..end_time, hour)
    hour #=> Time object set to hour
end

您可以迭代Time对象,但它会在两者之间每秒返回一次.我真正需要的是一种设置偏移量或增量值的方法(例如分钟,小时等)

这是内置于Ruby,还是有一个像样的插件?



1> Zach Langley..:

在1.9之前,您可以使用Range#step:

(start_time..end_time).step(3600) do |hour|
  # ...
end

然而,这种策略非常缓慢,因为它会调用Time#succ3600次.相反,正如dolzenko在他的回答中所指出的,更有效的解决方案是使用一个简单的循环:

hour = start_time
while hour < end_time
  # ...
  hour += 3600
end

如果你正在使用Rails,你可以用3600代替1.hour,这显然更具可读性.


Range#step对Ruby 1.9.2p180和1.9.3中的Time对象不起作用.它说:TypeError:无法从Time迭代.

2> dolzenko..:

如果您start_timeend_time实际上是Time类的实例,那么使用Range#step它的解决方案将是非常低效的,因为它会在此范围内迭代每秒Time#succ.如果将时间转换为整数,则会使用简单的加法,但这样您最终会得到类似的结果:

(start_time.to_i..end_time.to_i).step(3600) do |hour|
  hour = Time.at(hour)     
  # ...
end

但这也可以通过更简单,更高效(即没有所有类型转换)循环来完成:

hour = start_time
begin
  # ...      
end while (hour += 3600) < end_time


比接受的答案要好得多的解决方案.

3> Xenofex..:

在这种情况下,范围#step方法非常慢.使用begin..end,正如dolzenko发布在这里.

您可以定义一个新方法:

  def time_iterate(start_time, end_time, step, &block)
    begin
      yield(start_time)
    end while (start_time += step) <= end_time
  end

然后,

start_time = Time.parse("2010/1/1")
end_time = Time.parse("2010/1/31")
time_iterate(start_time, end_time, 1.hour) do |t|
  puts t
end

如果在铁轨.

推荐阅读
小白也坚强_177
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有