내 응용 프로그램 컨트롤러에 다음이 있습니다.
def is_number?(object)
true if Float(object) rescue false
end
내 컨트롤러의 다음 조건 :
if mystring.is_number?
end
조건에서 undefined method
오류가 발생합니다. 내가 is_number
잘못 정의한 것 같은데 …?
답변
생성 is_number?
방법.
도우미 메서드를 만듭니다.
def is_number? string
true if Float(string) rescue false
end
그리고 다음과 같이 부릅니다.
my_string = '12.34'
is_number?( my_string )
# => true
String
클래스 확장 .
is_number?
도우미 함수에 매개 변수로 전달하는 대신 문자열에서 직접 호출 할 수 있도록하려면 다음 과 같이 클래스 is_number?
의 확장으로 정의해야합니다 String
.
class String
def is_number?
true if Float(self) rescue false
end
end
그리고 다음과 같이 호출 할 수 있습니다.
my_string.is_number?
# => true
답변
다음은이 문제를 해결하는 일반적인 방법에 대한 벤치 마크입니다. 어느 것을 사용해야할지는 예상되는 잘못된 사례의 비율에 따라 달라질 수 있습니다.
- 상대적으로 드문 경우 캐스팅이 확실히 가장 빠릅니다.
- 잘못된 경우가 흔하고 int 만 확인하는 경우 비교 대 변환 된 상태가 좋은 옵션입니다.
- 잘못된 경우가 흔하고 float를 확인하는 경우 regexp가 아마도 갈 길일 것입니다.
성능이 중요하지 않은 경우 원하는 것을 사용하십시오. 🙂
정수 검사 세부 사항 :
# 1.9.3-p448
#
# Calculating -------------------------------------
# cast 57485 i/100ms
# cast fail 5549 i/100ms
# to_s 47509 i/100ms
# to_s fail 50573 i/100ms
# regexp 45187 i/100ms
# regexp fail 42566 i/100ms
# -------------------------------------------------
# cast 2353703.4 (±4.9%) i/s - 11726940 in 4.998270s
# cast fail 65590.2 (±4.6%) i/s - 327391 in 5.003511s
# to_s 1420892.0 (±6.8%) i/s - 7078841 in 5.011462s
# to_s fail 1717948.8 (±6.0%) i/s - 8546837 in 4.998672s
# regexp 1525729.9 (±7.0%) i/s - 7591416 in 5.007105s
# regexp fail 1154461.1 (±5.5%) i/s - 5788976 in 5.035311s
require 'benchmark/ips'
int = '220000'
bad_int = '22.to.2'
Benchmark.ips do |x|
x.report('cast') do
Integer(int) rescue false
end
x.report('cast fail') do
Integer(bad_int) rescue false
end
x.report('to_s') do
int.to_i.to_s == int
end
x.report('to_s fail') do
bad_int.to_i.to_s == bad_int
end
x.report('regexp') do
int =~ /^\d+$/
end
x.report('regexp fail') do
bad_int =~ /^\d+$/
end
end
플로트 검사 세부 정보 :
# 1.9.3-p448
#
# Calculating -------------------------------------
# cast 47430 i/100ms
# cast fail 5023 i/100ms
# to_s 27435 i/100ms
# to_s fail 29609 i/100ms
# regexp 37620 i/100ms
# regexp fail 32557 i/100ms
# -------------------------------------------------
# cast 2283762.5 (±6.8%) i/s - 11383200 in 5.012934s
# cast fail 63108.8 (±6.7%) i/s - 316449 in 5.038518s
# to_s 593069.3 (±8.8%) i/s - 2962980 in 5.042459s
# to_s fail 857217.1 (±10.0%) i/s - 4263696 in 5.033024s
# regexp 1383194.8 (±6.7%) i/s - 6884460 in 5.008275s
# regexp fail 723390.2 (±5.8%) i/s - 3613827 in 5.016494s
require 'benchmark/ips'
float = '12.2312'
bad_float = '22.to.2'
Benchmark.ips do |x|
x.report('cast') do
Float(float) rescue false
end
x.report('cast fail') do
Float(bad_float) rescue false
end
x.report('to_s') do
float.to_f.to_s == float
end
x.report('to_s fail') do
bad_float.to_f.to_s == bad_float
end
x.report('regexp') do
float =~ /^[-+]?[0-9]*\.?[0-9]+$/
end
x.report('regexp fail') do
bad_float =~ /^[-+]?[0-9]*\.?[0-9]+$/
end
end
답변
class String
def numeric?
return true if self =~ /\A\d+\Z/
true if Float(self) rescue false
end
end
p "1".numeric? # => true
p "1.2".numeric? # => true
p "5.4e-29".numeric? # => true
p "12e20".numeric? # true
p "1a".numeric? # => false
p "1.2.3.4".numeric? # => false
답변
발생한 예외에 의존하는 것은 가장 빠르고 읽기 쉽고 신뢰할 수있는 솔루션이 아닙니다.
다음을 수행합니다.
my_string.should =~ /^[0-9]+$/
답변
Ruby 2.6.0부터 숫자 형 캐스트 메소드에는 선택적 exception
-argument [1]이 있습니다. 이를 통해 예외를 제어 흐름으로 사용하지 않고 내장 메서드를 사용할 수 있습니다.
Float('x') # => ArgumentError (invalid value for Float(): "x")
Float('x', exception: false) # => nil
따라서 자신 만의 방법을 정의 할 필요없이 직접 변수를 확인할 수 있습니다.
if Float(my_var, exception: false)
# do something if my_var is a float
end
답변
이게 내가하는 방법이지만 더 나은 방법이있을 것 같아
object.to_i.to_s == object || object.to_f.to_s == object
답변
아니 당신은 그것을 잘못 사용하고 있습니다. 당신의 is_number? 논쟁이 있습니다. 당신은 논쟁없이 그것을 불렀다
is_number를해야합니까? (mystring)