【问题标题】:Ruby: Best way to convert a String to Integer or leave it as String if necessary?Ruby:将字符串转换为整数或在必要时将其保留为字符串的最佳方法?
【发布时间】:2011-04-14 20:14:32
【问题描述】:

开发一个小型调查 web 应用程序时遇到了处理评级类型问题范围的问题。 所以评分的范围可能是:

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

等等

范围在数据库中存储为一对 varchars(范围的开始和结束)。所以 range 总是以字符串输入开始。

获取这些字符串值并相应地构建 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

有什么想法吗?

【问题讨论】:

    标签: ruby string integer


    【解决方案1】:

    使用 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"]
    

    【讨论】:

    • a = (a.to_i == 0 && a != "0") ? a : a.to_i 可能做不到我们想要的;如果 a = "1,234" 结果将为 1。
    • 1,234 == 1234 还是 1.234?在第一种情况下,如果您在数据库中存储带有分隔符的整数并且您的输入应该被清理,我认为您的设计很糟糕。如果你仍然这样做,修复很容易从字符串中删除所有逗号,然后再将它们转换为整数 (gsub('.',''))。如果它是浮点数,请检查字符串中的点并在其上调用 .to_f。 (尽管在上面的用例中,带有浮点数的范围没有多大意义)
    【解决方案2】:

    您可以执行以下操作。

    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
    

    这会同时处理正负范围

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-21
      • 1970-01-01
      • 2017-12-08
      • 2010-09-06
      • 2014-04-23
      • 2010-10-10
      • 2011-04-13
      相关资源
      最近更新 更多