在给定时间戳的Ruby时间戳数组中查找下一个和上一个时间戳

时间:2013-07-27 21:32:40

标签: ruby timestamp

所以,如果我有一个像这样的时间戳数组(实际上比这更多):

2013-07-27 18:02:59.865572
2013-07-27 18:29:00.132601
2013-07-27 19:00:00.081585
2013-07-27 19:29:00.273857
2013-07-27 20:00:00.011761

我想找到哪两个时间戳 2013-07-27 19:13:00.081585 介于两者之间,什么是Ruby最优雅的方式?

我可以设想一个丑陋的循环和if语句来做到这一点,但作为一个新手Ruby程序员,我怀疑有一个更优雅的方法来做到这一点(我绝对找不到!)。

谢谢!

2 个答案:

答案 0 :(得分:1)

这取决于一些事情。

  • 您所查找的时间戳是否已知在阵列中。
  • 之间的意味着什么。
  • 数组中的元素是否唯一。

让我们假设数组已经排序,或者你事先自己排序。

如果已知your_timestamp在数组中,您可以使用timestamp_array.index(your_timestamp)找到其索引。从逻辑上讲,your_timestamp介于其间的元素将具有紧接在上方和下方的索引。有两件事需要注意。

  1. 从阵列的两端掉下来。
  2. 重复的时间戳。
  3. 如果your_timestamp是数组中的第一个或最后一个元素,则不会有一个元素的索引紧接在第一个元素之下或紧接在最后一个元素之上。

    如果您的数组包含重复的时间戳,则您可能会返回your_timestamp作为其中一个值。看起来你想要这样做,但这里没有严格的正确或错误的答案。它依赖于应用程序。

    如果你不知道your_timestamp是否在数组中,或者你想要your_timestamp作为其中一个值(除非它是第一个或排序数组的最后一个元素,即),这可能是一种更好的方法。

    timestamp_array.sort.each_cons(2){ |ts| 
      # If your desired timestamp is in the timestamp array, you'll
      # get at least two pairs of timestamps.
      answer.concat ts if your_desired_timestamp.between?(ts[0], ts[1])
    }
    # If you have more than 2 elements, return only the first and last element.
    if answer.length > 2
      answer = answer.first, answer.last
    end
    p answer
    
    ["2013-07-27 18:29:00.132601", "2013-07-27 19:29:00.273857"]
    

    这适用于重复的时间戳,并且没有从阵列的任何一端掉落的危险。

    可以进行一些优化。例如,您可以切换到二进制搜索(bsearch方法),如果您有非常大的数组,这可能是值得的;你可以消除条件if answer.length > 2;等

答案 1 :(得分:0)

所以其他人留下了答案,然后由于某种原因进行了编辑,我认为这是因为有错误,但它导致我朝着正确的方向发展,就像@squiguy一样。

timestamp_array.sort.each_cons(2).select{ |a,b|  
  puts a
    if a < your_desired_timestamp and b > your_desired_timestamp)
      puts 'this is the valid range for ' + your_desired_timestamp.to_s
    end
  puts b
}

感谢Guys和Gals!