Ruby 中有"greater than but less than"函数吗



我有一个数组:

times = [2, 5, 7.5, 8.5, 9, 10, 11.5, 13.5, 14.5, 17, 18, 19, 24]

我希望用户输入一个时间,说"11",然后返回"11.5"(times.index(6)),因为它大于10但小于11.5

有没有办法在 Ruby 中做到这一点?

我的回答建议在times很大时有效的方法。

如果像问题中一样,times被排序,我们可能需要执行二叉搜索:

times = [2, 5, 7.5, 8.5, 9, 10, 11.5, 13.5, 14.5, 17, 18, 19, 24]
times.bsearch { |x| x >= 11 }
#=> 11.5

如果times.max < 11,则返回nil

参见 Array#bsearch。

现在假设times没有排序:

times.shuffle!
#=> [7.5, 2, 14.5, 9, 17, 5, 19, 24, 8.5, 11.5, 13.5, 10, 18] 

当然,我们可以对times进行排序,然后应用bsearch,但排序是昂贵的,具有O(n*ln(n))的时间复杂度)。如果我们希望在不更改times的情况下对多个目标值(例如,1112...)重复该操作,则一次对times进行排序的开销可能是合理的,但是如果我们希望仅对单个目标值(例如11)执行该操作,则简单地执行线性搜索会更有效:

times.min_by { |n| n >= 11 ? (n-11) : Float::INFINITY }
#=> 11.5

如果times.max < 11,则返回Float::INFINITY

请参阅枚举#min_by。

使用范围和===

如果 obj 介于范围的开始和结束之间,则返回true,否则false返回(与cover?相同)。

(1..5) === 0 # => false
(1..5) === 1 # => true
(1..5) === 5 # => true
(1..5) === 6 # => false

如果您希望范围是独占的,则可以使用...

(1...5) === 0 # => false
(1...5) === 1 # => true
(1...5) === 5 # => false
(1...5) === 6 # => false

但我不建议使用...。调试时更难发现,并且愚弄了不了解其工作原理的人,这可能会引入错误。

范围可以使用s. 构造。es...e文字,或带有 ::new。使用..构造的范围从头到尾(包括开头)。使用...创建的那些不包括结束值。

最好改用 4(或以前的值),这样可以完成相同的操作:

(1..4) === 0 # => false
(1..4) === 1 # => true
(1..4) === 5 # => false
(1..4) === 6 # => false

回到你的问题:

times = [2, 5, 7.5, 8.5, 9, 10, 11.5, 13.5, 14.5, 17, 18, 19, 24]
times.select { |i| (11 .. 11.5) === i } # => [11.5]

如果你想找到第一个大于给定数字的数字,假设数组是排序的,

times.find {  |time | time > given_time }

如果未对数组进行排序,请先对其进行排序

times.sort.find {  |time | time > given_time }

相关内容

  • 没有找到相关文章

最新更新