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

时间:2015-11-20 11:28:42

标签: 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-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+"

我可以使用传统的mapsplitselect方法组合来实现解决方案。但是,我只想要一个有效的解决方案。

3 个答案:

答案 0 :(得分:1)

▶ 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"

上述方法适用于任何checker区间,同时符合语法。

答案 1 :(得分:0)

嘿,您可以尝试这种方式,只需添加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)
    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 >= 10000 && a[:text].gsub('+','').to_i <= number)}
    puts (arr.first[:text] rescue "not in given range")
end

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

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

答案 2 :(得分:0)

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+"