在字符串数组中查找最接近的较小数字(ruby)

时间:2014-02-03 22:26:31

标签: ruby arrays

红宝石新手。我有一个由nokogiri创建的数组:

数组= [“10:31主标题”,......]

这是一种格式为小时:分钟标题的时间表。 现在我有时间,比如10:35,我想在数组中找到最接近的数字(时间和标题)。这就像现在正在玩的那样?

我怎样才能在红宝石中做到这一点?我在这里一片空白......

谢谢

4 个答案:

答案 0 :(得分:2)

您可以使用下面的bsearch

来实现此目的

a = [1,4,8,11,97]

a.bsearch {| x | x> = 7}#,结果为8

答案 1 :(得分:1)

您将需要遍历数组并解析每个条目。您还必须考虑时间是12小时还是24小时,例如: “10:31主标题”是指上午10:31或下午(12小时制)。如果它是一个24小时制,那么10:31是10:31 [am],你也将有22:31来反映10:31 [pm]。

因此,您可以遍历数组,解析每个条目,然后构建一个可以排序的新结构。最终,您可以获得最低值,然后在原始数组中找到该条目的索引。

答案 2 :(得分:0)

由于您的数组包含以数字开头的字符串,因此这些字符串可以很好地自然排序。

my_array.sort.reverse.find{ |i| i < "10:35" }

这将按升序对数组进行排序,然后将其反转,最后返回块返回true的第一个项目。

如果您使用的是Ruby版本&gt; 2.0,您也可以使用Array#bsearch

my_array.sort.bsearch{ |i| i < "10:35" }

这将对您的数组进行排序,然后使用二进制搜索方法来查找所需的项目(感谢@ala指出这一点)。

这些简单的代码行期望时间为24h格式,前导零(即hh:mm),因为它依赖于按字典顺序比较行。

答案 3 :(得分:0)

require 'date'
a1 = ["10:31 The Beastmaster", "10:36 C.H.U.D.", "11:30 Goonies", "11:30 Krull", "11:59 Batteries Not Included"]
#=> ["10:31 The Beastmaster", "10:36 C.H.U.D.", "11:30 Goonies", "11:30 Krull", "11:59 Batteries Not Included"]
h1 = {}; a1.each {|x| m = x.match(/(\d{1,2}:\d{2})\s+(\w.*)/); h1[m[1]] ||= []; h1[m[1]] << m[2]}; h1 # => hash with times as keys and array of titles as corresponding values
#=> {"10:31"=>["The Beastmaster"], "10:36"=>["C.H.U.D."], "11:30"=>["Goonies", "Krull"], "11:59"=>["Batteries Not Included"]}
t1 = DateTime.rfc3339('2014-02-03T10:35:00-08:00').to_time.to_i
#=> 1391452500
within_an_hour = 60 * 60
#=> 3600
t2 = t1 + within_an_hour
#=> 1391456100
a2 = h1.keys.partition {|x| x > Time.at(t1).strftime("%I:%M")}[0] # => all upcoming times
#=> ["10:36", "11:30", "11:59"]
h2 = {}; a2.each {|x| h2[x] = h1[x]}; h2 # => all upcoming show times with corresponding titles
#=> {"10:36"=>["C.H.U.D."], "11:30"=>["Goonies", "Krull"], "11:59"=>["Batteries Not Included"]}
a3 = a2.partition {|x| x < Time.at(t2).strftime("%I:%M")}[0] # => upcoming times within an hour
#=> ["10:36", "11:30"]
h3 = {}; a3.each {|x| h3[x] = h1[x]}; h3 # => upcoming show times with corresponding titles within an hour
#=> {"10:36"=>["C.H.U.D."], "11:30"=>["Goonies", "Krull"]}

在方法中使用上述代码:

require 'date'
def what_is_playing_now(time, a1=["10:31 The Beastmaster", "10:36 C.H.U.D.", "11:30 Goonies", "11:30 Krull", "11:59 Batteries Not Included"])
  h1 = {}; a1.each {|x| m = x.match(/(\d{1,2}:\d{2})\s+(\w.*)/); h1[m[1]] ||= []; h1[m[1]] << m[2]}; h1 # => hash with times as keys and array of titles as corresponding values
  t1 = DateTime.rfc3339("2014-02-03T#{time}:00-08:00").to_time.to_i
  a2 = h1.keys.partition {|x| x > Time.at(t1).strftime("%I:%M")}[0] # => all upcoming times
  h2 = {}; a2.each {|x| h2[x] = h1[x]}; h2 # => all upcoming show times with corresponding titles
  "#{a2.first} #{h2[a2.first].sort.first}"
end
what_is_playing_now("10:35")
#=> "10:36 C.H.U.D."

来源: