开发一个小调查webapp,遇到了处理评级类型问题范围的问题。 所以评级的范围可能是:
1..10
-5..0
-5..5
'a'..'z'
'E'..'M'
等等
范围存储为数据库中的一对varchars(范围的开始和结束)。因此,范围始终以字符串输入开始。
获取这些字符串值并相应地构建Ruby Range的最佳方法是什么。 我不能只去value.to_i,因为这对字符串迭代不起作用。有一堆if似乎很难看。有更好的方法吗?
不那么重要,但值得一提: 如果我想让它全部与反转范围一起工作怎么办?说5到0或G到A。我知道Ruby不支持反向范围(因为它使用succ()来迭代)。这里最好的方法是什么?
提前致谢!
更新
根据Wouter de Bie的建议,我已经解决了这个问题:
def to_int_or_string(str)
return str.match(/^-?\d+$/) ? str.to_i : str.strip
end
def ratings_array(from, to)
from = to_int_or_string(from)
to = to_int_or_string(to)
from > to ? Range.new(to, from).to_a.reverse : Range.new(from, to).to_a
end
有什么想法吗?
答案 0 :(得分:2)
使用Range.new:
Range.new("a","z")
=> "a".."z"
Range.new(-5,5)
=> -5..5
如果varchars包含引号,则可以使用eval来获取正确的范围:
from = "'a'"
to = "'z'"
eval("Range.new(#{from},#{to})")
否则你可以使用value.to_i来确定它是varchar中的数字还是字符串:
a = "x"
a = (a.to_i == 0 && a != "0") ? a : a.to_i
=> "x"
a = "5"
a = (a.to_i == 0 && a != "0") ? a : a.to_i
=> 5
当然可以很好地将其提取到方法中:
def to_int_or_string(value)
return (value.to_i == 0 && value != "0") ? value : value.to_i
end
def to_range(from, to)
return Range.new(to_int_or_string(from), to_int_or_string(to))
end
要反转您的范围,您必须先将其转换为数组:
Range.new("a","g").to_a.reverse
=> ["g", "f", "e", "d", "c", "b", "a"]
答案 1 :(得分:0)
您可以执行以下操作。
str = 'Z..M'
v1 = str[0,str.index('.')]
v2 = str[str.index('.')+2, str.length]
unless v1.to_i == 0
v1 = v1.to_i
v2 = v2.to_i
end
if v2>v1
final_arr = (v1..v2).to_a
else
final_arr = (v2..v1).to_a.reverse
end
puts final_arr
这样可以处理正范围和负范围