2016-04-25 84 views
1

比方说,我有开始和结束时间的一些用户输入:红宝石遍历小时

  • 开始= 09:00
  • 结束= 01:00

如何显示全部那两个小时之间的时间?因此,从09到23,0,然后到1

有简单的情况:

  • 开始= 01:00
  • 结束= 04:00

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

+0

我在这里假设跨度时间总是23小时或更少,对不对? – tadman

回答

3

这可以用自定义枚举器实现来解决:

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

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 
+0

'小时'只在ActiveSupport和Rails中可用。 'end'是一个你不能使用它的关键字。 –

+0

很好,谢谢 – alexanderbird

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之间)

:)如果你想整理小时使用..而不是... =>[0..end_h - start_h]

如果您关心性能或想要延迟评估一些事情,您还可以执行以下操作ading代码非常清晰):

(0..23).lazy.map {|h| (h + start_h) % 24 }.take_while { |h| h != end_h } 
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]符号。