Ruby:将字符串转换为整数或在必要时将其保留为字符串的最佳方法?

发布于 2024-09-24 04:48:04 字数 750 浏览 1 评论 0原文

开发一个小型调查网络应用程序,遇到了处理评级类型问题范围的问题。 因此,评级的范围可以是:

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

等等

该范围作为一对 varchar 存储在数据库中(范围的开始和结束)。因此范围始终以字符串输入开始。

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

有什么想法吗?

Developing a little survey webapp, ran into problem that deals with ranges for rating type questions.
So a rating's range could be:

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

and so on

The range is stored as a pair of varchars in database (start and end of range). So range always starts off as a string input.

What is the best way to take these string values and build a Ruby Range accordingly.
I can't just go value.to_i as this won't work for string iteration. Having a bunch of if's seems ugly. Any better way?

Not as important, but worth asking:
Also what if I wanted to make it all work with reversed range? Say 5-to-0 or G-to-A. I know that Ruby doesn't support reverse range (since it uses succ() to iterate). What would be the best way here?

Thanks in advance!

Update:

Based on Wouter de Bie's suggestion I've settled for this:

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

Any thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

℉絮湮 2024-10-01 04:48:05

您可以执行以下操作。

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

这同时考虑了正值和负值范围

You can do something like the following.

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

This takes care of both the positive and the negative ranges

眼中杀气 2024-10-01 04:48:04

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

Use Range.new:

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

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

If you're varchars contain quotes, you can use eval to get the right ranges:

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

Otherwise you could use value.to_i to figure out if it was a number or a string in the 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

Which of course can be nicely extracted into a method:

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

To reverse your range, you have to convert it to an array first:

Range.new("a","g").to_a.reverse
=> ["g", "f", "e", "d", "c", "b", "a"]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文