Ruby 从范围字符串中查找数字所属的范围

Ruby 从范围字符串中查找数字所属的范围,ruby,Ruby,我有一个哈希数组,如下所示: [{:id=>1, :text=>"1-10"}, {:id=>2, :text=>"11-50"}, {:id=>3, :text=>"51-200"}, {:id=>4, :text=>"201-500"}, {:id=>5, :text=>"501-1000"}, {:id=>6, :text=>"1001-5000"}, {:id=>7, :text=>"5001

我有一个哈希数组,如下所示:

[{:id=>1, :text=>"1-10"},
 {:id=>2, :text=>"11-50"},
 {:id=>3, :text=>"51-200"},
 {:id=>4, :text=>"201-500"},
 {:id=>5, :text=>"501-1000"},
 {:id=>6, :text=>"1001-5000"},
 {:id=>7, :text=>"5001-10000"},
 {:id=>8, :text=>"10000+"}]
给定一个数字,我必须找出它属于哪个散列,并获取该散列的文本值。输出应该类似于:

test(7000) # => "5001-10000"
test(700) # => "501-1000"
test(321) # => "201-500"
test(95) # => "51-200"
test(501) # => "501-1000"
test(20000) # => "10000+"
我可以用传统的map、split和select方法组合来实现解决方案。但是,我只想要一个有效的解决方案

▶ CHECKER = [{:id=>1, :text=>"1-10"},
▷   {:id=>2, :text=>"11-50"}, 
▷   {:id=>3, :text=>"51-200"}, 
▷   {:id=>4, :text=>"201-500"}, 
▷   {:id=>5, :text=>"501-1000"}, 
▷   {:id=>6, :text=>"1001-5000"}, 
▷   {:id=>7, :text=>"5001-10000"}, 
▷   {:id=>8, :text=>"10000+"}] 
▶ def test input, checker = CHECKER
▷   checker.map do |r| 
▷     instance_eval(r[:text].sub(/\+$/, '-Float::INFINITY').sub(/-/, '..'))
▷   end.detect do |r| 
▷     r === input
▷   end.to_s.sub(/\.+/, '-').sub(/\.\.Infinity/, '+')
▷​ end
▶ test 700
#⇒ "501-1000"

上述方法适用于符合语法的任何检查间隔。

嘿,您可以尝试这种方法,只需添加最终范围值,如10000+pa为数组

 pa = [{:id=>1, :text=>"1-10"},
 {:id=>2, :text=>"11-50"},
 {:id=>3, :text=>"51-200"},
 {:id=>4, :text=>"201-500"},
 {:id=>5, :text=>"501-1000"},
 {:id=>6, :text=>"1001-5000"},
 {:id=>7, :text=>"5001-10000"},
 {:id=>8, :text=>"10000+"}]
方法

如果您不知道最终的范围,那么您可以找到它作为。对于任何类型的间隔

def test(number)
       final_value = pa.select{|a| a[:text] if a[:text].include? "+"}.first[:text]
        arr = pa.select{|a| a[:text] if  (a[:text].split("-")[0].to_i <= number && a[:text].split("-")[1].to_i >= number) || (a[:text].gsub('+','').to_i >= final_value.gsub('+','').to_i && a[:text].gsub('+','').to_i <= number)}
        puts (arr.first[:text] rescue "not in given range")
end

当然你已经知道stackoverflow不是这样工作的,也许你需要我试过的。我已经尝试并能够实现与传统地图、分割和选择方法组合的解决方案。但是,我只是想要一个有效的解决方案,所以张贴在。很抱歉没有发布我的尝试。@DickieBoy严肃地说。。。。。否。代码审阅审阅代码。。。。这里的密码在哪里?@rolfl touch。虽然我是指上面的评论。首先。。。阅读我的第一条评论,然后阅读回复中的评论,解决方案已经实现,但是@Vamsi需要一种更有效的方法。这就是为什么我给了代码审查。
def test(number)
       final_value = pa.select{|a| a[:text] if a[:text].include? "+"}.first[:text]
        arr = pa.select{|a| a[:text] if  (a[:text].split("-")[0].to_i <= number && a[:text].split("-")[1].to_i >= number) || (a[:text].gsub('+','').to_i >= final_value.gsub('+','').to_i && a[:text].gsub('+','').to_i <= number)}
        puts (arr.first[:text] rescue "not in given range")
end
def test (number)

myranges = [{:id=>1, :text=>"1-10"},{:id=>2, :text=>"11-50"}, {:id=>3, :text=>"51-200"}, {:id=>4, :text=>"201-500"}, {:id=>5, :text=>"501-1000"}, {:id=>6, :text=>"1001-5000"}, {:id=>7, :text=>"5001-10000"}, {:id=>8, :text=>"10000+"}]
 if number < 1
    "Not in range"
 elsif number > 10000
    "10000+"
 else
    myranges[0..-2].select{|a|  p a[:text] if eval(a[:text].split('-').join("..")).include?(number)}
 end
end

> test 7000
#=> "5001-10000"
> test 0
#=> "Not in range"
> test 20000
#=> "10000+"