2010-09-20 50 views
2

開發一個小調查web​​app,遇到問題,處理評分類型問題的範圍。 所以評級的範圍可以是:Ruby:將String轉換爲Integer的最佳方式,或者在必要時將其保留爲String?

1..10 
-5..0 
-5..5 
'a'..'z' 
'E'..'M' 

範圍被存儲在數據庫中對VARCHAR處理的(開始和結束的範圍)。所以範圍總是以字符串輸入開始。

什麼是最好的方式來採取這些字符串值並相應地建立一個Ruby範圍。 我不能只是去value.to_i,因爲這對字符串迭代不起作用。有一堆if似乎很難看。有更好的方法嗎?

不一樣重要,但值得問: 另外如果我想使所有的工作與反向範圍?說5到0或G到A。我知道Ruby不支持反向範圍(因爲它使用succ()來迭代)。這裏最好的方法是什麼?

提前致謝!

更新:

基於沃特·德憋的建議,我已經決定在此:

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 

有什麼想法?

回答

2

使用Range.new的護理:

Range.new("a","z") 
=> "a".."z" 

Range.new(-5,5) 
=> -5..5 

如果你VARCHAR處理包含引號,你可以使用eval得到正確的範圍:

from = "'a'" 
to = "'z'" 
eval("Range.new(#{from},#{to})") 

否則,您可以使用value.to_i來確定它是數字還是str荷蘭國際集團在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"] 
+0

a =(a.to_i == 0 && a!=「0」)? a:a.to_i可能不會做所期望的事情;如果a =「1,234」,結果將爲1. – steenslag 2010-09-20 21:58:03

+0

好點。但我不期望數字是那麼大 – Swartz 2010-09-20 23:40:54

+0

1,234 == 1234或1.234?在第一種情況下,如果您在數據庫中存儲帶有分隔符的整數並且應該對您的輸入進行消毒,我認爲您的設計很糟糕。 無論如何,修正很容易從字符串中刪除所有逗號,然後將它們轉換爲整數(gsub('。',''))。如果它是一個浮點數,請檢查字符串中的一個點,並在其上調用.to_f。 (雖然在上面的用例中浮點數的範圍沒有多大意義) – xinit 2010-09-21 05:58:03

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 

這需要正和負範圍

相關問題