【问题标题】:Ruby iterate over hoursRuby 迭代数小时
【发布时间】:2016-04-25 15:03:30
【问题描述】:

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

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

如何显示这两个时间之间的所有时间?所以从 09 到 23、0,然后到 1。

有简单的案例:

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

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

【问题讨论】:

  • 我在这里假设时间跨度总是 23 小时或更短,对吧?

标签: ruby loops time


【解决方案1】:

这可以通过自定义 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]

【讨论】:

    【解决方案2】:

    你可以做一个单线器(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]

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

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

    【讨论】:

      【解决方案3】:

      有一个简单的条件:

      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] 表示法。

      【讨论】:

        【解决方案4】:

        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
        

        【讨论】:

        • hours 仅在 ActiveSupport 和 Rails 中可用。还有end是关键字,不能用。
        猜你喜欢
        • 1970-01-01
        • 2018-09-04
        • 2016-05-16
        • 2012-05-03
        • 2011-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多