Ruby迭代了几个小时

时间:2016-04-25 15:03:30

标签: ruby loops time

假设我有一些用户输入的开始和结束时间:

  • start = 09:00
  • end = 01:00

如何显示这两者之间的所有小时数?所以从09到23,0,再到1。

有一些简单的案例:

  • start = 01:00
  • end = 04:00

这只是一个问题 ((start_hour.to_i)..(end_hour.to_i))。选择{|小时| }

4 个答案:

答案 0 :(得分:3)

这可以通过自定义Enumerator实现来解决:

def hours(from, to)
  Enumerator.new do |y|
    while (from != to)
      y << from
      from += 1
      from %= 24
    end
    y << from
  end
end

这给你一些你可以这样使用的东西:

hours(9, 1).each do |hour|
  puts hour
end

或者如果你想要一个数组:

hours(9,1).to_a
#=> [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 1]

答案 1 :(得分:1)

你可以做一个oneliner (0..23).to_a.rotate(start_h)[0...end_h - start_h]

def hours_between(start_h, end_h)
    (0..23).to_a.rotate(start_h)[0...end_h - start_h]
end

hours_between(1, 4)
# [1, 2, 3]
hours_between(4, 4)
# []
hours_between(23, 8)
# [23, 0, 1, 2, 3, 4, 5, 6, 7]

不要忘记清理输入(它们是0到23之间的数字):)

如果您希望结束时间使用..而不是... =&gt; [0..end_h - start_h]

如果您关心性能或想要懒惰地评估某些内容,您还可以执行以下操作(阅读代码非常清楚):

(0..23).lazy.map {|h| (h + start_h) % 24 }.take_while { |h| h != end_h }

答案 2 :(得分:0)

条件简单:

def hours(from, to)
  if from <= to
    (from..to).to_a
  else
    (from..23).to_a + (0..to).to_a
  end
end

hours(1, 9)
#=> [1, 2, 3, 4, 5, 6, 7, 8, 9]

hours(9, 1)
#=> [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 1]

您也可以使用更短但更隐秘的[*from..23, *0..to]符号。

答案 3 :(得分:-1)

https://stackoverflow.com/a/6784628/3012550显示了如何迭代两次之间距离的小时数。

我会使用它,并在每次迭代时使用start + i.hours

def hours(number)
  number * 60 * 60
end

((end_time - start_time) / hours(1)).round.times do |i|
  print start_time + hours(i)
end