[RUBY-ON-RAILS] 테스트 문자열은 루비 온 레일즈의 숫자 인 경우
RUBY-ON-RAILS테스트 문자열은 루비 온 레일즈의 숫자 인 경우
내 응용 프로그램 컨트롤러에 다음이있다 :
def is_number?(object)
true if Float(object) rescue false
end
내 컨트롤러에 다음과 같은 조건 :
if mystring.is_number?
end
조건은 미정있어서 오류를 던지고. 내가 잘못된 위치에 is_number 정의한 같은데요 ...?
해결법
-
==============================
1.도우미 메서드를 만듭니다
도우미 메서드를 만듭니다
def is_number? string true if Float(string) rescue false end
그리고 다음과 같이 호출 :
my_string = '12.34' is_number?( my_string ) # => true
당신은 is_number 전화를 할 수있게하려면? 대신 직접 도우미 함수에 PARAM로 전달하는 문자열에, 당신은 is_number 정의 할 필요가? 그래서 같은 String 클래스의 확장으로 :
class String def is_number? true if Float(self) rescue false end end
그리고 당신은 그것을로 호출 할 수 있습니다 :
my_string.is_number? # => true
-
==============================
2.다음은이 문제를 해결하기위한 일반적인 방법에 대한 벤치 마크입니다. 당신은 아마 사용해야 하나의 참고가 예상 거짓 케이스의 비율에 따라 달라집니다.
다음은이 문제를 해결하기위한 일반적인 방법에 대한 벤치 마크입니다. 당신은 아마 사용해야 하나의 참고가 예상 거짓 케이스의 비율에 따라 달라집니다.
성능은 문제가 당신이 좋아하는 무엇을 사용하지 않는 경우. :-)
# 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
-
==============================
3.
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
-
==============================
4.제기 예외에 의존하는 것은 가장 빠른, 읽을 수없고 신뢰할 수있는 솔루션이 아닙니다. 나는 다음을 수행 할 것입니다 :
제기 예외에 의존하는 것은 가장 빠른, 읽을 수없고 신뢰할 수있는 솔루션이 아닙니다. 나는 다음을 수행 할 것입니다 :
my_string.should =~ /^[0-9]+$/
-
==============================
5.이것은 내가 그것을 할 방법입니다,하지만 난 더 나은 방법이있을 너무 생각
이것은 내가 그것을 할 방법입니다,하지만 난 더 나은 방법이있을 너무 생각
object.to_i.to_s == object || object.to_f.to_s == object
-
==============================
6.어떤 당신은 잘못을 사용하고 있습니다. 당신의 is_number? 인수가 있습니다. 당신은 인수없이 호출
어떤 당신은 잘못을 사용하고 있습니다. 당신의 is_number? 인수가 있습니다. 당신은 인수없이 호출
당신은 is_number 일을해야 하는가? (mystring에)
-
==============================
7.TL; DR : 사용 정규식 접근 방식. 더 빠른 허용 대답의 구조 방식에 비해 39x이며, 또한 "1000"와 같은 경우를 처리
TL; DR : 사용 정규식 접근 방식. 더 빠른 허용 대답의 구조 방식에 비해 39x이며, 또한 "1000"와 같은 경우를 처리
def regex_is_number? string no_commas = string.gsub(',', '') matches = no_commas.match(/-?\d+(?:\.\d+)?/) if !matches.nil? && matches.size == 1 && matches[0] == no_commas true else false end end
--
@Jakob S에 의해 허용 대답은 대부분 작동하지만, 예외를 잡기 정말 속도가 느려질 수 있습니다. 또한, 구조 방식은 "1000"와 같은 문자열에 실패합니다.
하자는 방법을 정의 :
def rescue_is_number? string true if Float(string) rescue false end def regex_is_number? string no_commas = string.gsub(',', '') matches = no_commas.match(/-?\d+(?:\.\d+)?/) if !matches.nil? && matches.size == 1 && matches[0] == no_commas true else false end end
그리고 지금 어떤 테스트 케이스 :
test_cases = { true => ["5.5", "23", "-123", "1,234,123"], false => ["hello", "99designs", "(123)456-7890"] }
그리고 약간의 코드는 테스트 케이스를 실행합니다 :
test_cases.each do |expected_answer, cases| cases.each do |test_case| if rescue_is_number?(test_case) != expected_answer puts "**rescue_is_number? got #{test_case} wrong**" else puts "rescue_is_number? got #{test_case} right" end if regex_is_number?(test_case) != expected_answer puts "**regex_is_number? got #{test_case} wrong**" else puts "regex_is_number? got #{test_case} right" end end end
여기에 테스트 케이스의 출력은 다음과 같습니다
rescue_is_number? got 5.5 right regex_is_number? got 5.5 right rescue_is_number? got 23 right regex_is_number? got 23 right rescue_is_number? got -123 right regex_is_number? got -123 right **rescue_is_number? got 1,234,123 wrong** regex_is_number? got 1,234,123 right rescue_is_number? got hello right regex_is_number? got hello right rescue_is_number? got 99designs right regex_is_number? got 99designs right rescue_is_number? got (123)456-7890 right regex_is_number? got (123)456-7890 right
시간은 약간의 성능 벤치 마크를 할 수 :
Benchmark.ips do |x| x.report("rescue") { test_cases.values.flatten.each { |c| rescue_is_number? c } } x.report("regex") { test_cases.values.flatten.each { |c| regex_is_number? c } } x.compare! end
그리고 결과 :
Calculating ------------------------------------- rescue 128.000 i/100ms regex 4.649k i/100ms ------------------------------------------------- rescue 1.348k (±16.8%) i/s - 6.656k regex 52.113k (± 7.8%) i/s - 260.344k Comparison: regex: 52113.3 i/s rescue: 1347.5 i/s - 38.67x slower
-
==============================
8.레일 4에서는 둘 필요가 File.expand_path ( '../../ LIB', __FILE__)가 필요 + '/ 내선 / 문자열' 당신의 설정 / application.rb에서
레일 4에서는 둘 필요가 File.expand_path ( '../../ LIB', __FILE__)가 필요 + '/ 내선 / 문자열' 당신의 설정 / application.rb에서
-
==============================
9.루비 2.6.0로, 숫자 캐스트 방법은 선택적 예외 인자 [1]이있다. 이 사용하는 우리를있게 내장 된 제어 흐름과 같은 예외를 사용하지 않고 방법 :
루비 2.6.0로, 숫자 캐스트 방법은 선택적 예외 인자 [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
-
==============================
10.당신은 논리의 일부로 사용 예외하지 않으려면, 당신은이를 시도 할 수 있습니다 :
당신은 논리의 일부로 사용 예외하지 않으려면, 당신은이를 시도 할 수 있습니다 :
class String def numeric? !!(self =~ /^-?\d+(\.\d*)?$/) end end
또는, 당신이 모든 개체 클래스에서 작동 문자열로 클래스 객체에 변환 자체를 클래스 문자열을 교체하려면 : !! (self.to_s = ~ /^-?\d+(\.\d*)?$/ )
-
==============================
11.다음 함수를 사용합니다 :
다음 함수를 사용합니다 :
def is_numeric? val return val.try(:to_f).try(:to_s) == val end
그래서,
각각 is_numeric? "1.2f"= 거짓
각각 is_numeric? "1.2"= 참
각각 is_numeric? "12F"= 거짓
각각 is_numeric? "12"진정한 =
-
==============================
12.이 솔루션은 어떻게 바보입니까?
이 솔루션은 어떻게 바보입니까?
def is_number?(i) begin i+0 == i rescue TypeError false end end
from https://stackoverflow.com/questions/5661466/test-if-string-is-a-number-in-ruby-on-rails by cc-by-sa and MIT license
'RUBY-ON-RAILS' 카테고리의 다른 글
[RUBY-ON-RAILS] '필요'등의 파일을로드 할 수 없습니다 - '노코 기리 \ 노코 기리'(LoadError)을 실행할 때`server` 레일 (0) | 2020.02.07 |
---|---|
[RUBY-ON-RAILS] 루비 온 레일즈에서 코드를 넣어해야 String 클래스를 확장하는? (0) | 2020.02.07 |
[RUBY-ON-RAILS] 하나 개의 배열이 다른 배열의 모든 요소가 포함되어 있는지 확인하는 방법 (0) | 2020.02.07 |
[RUBY-ON-RAILS] 어떻게 명시 적으로 레일에서 모델의 테이블 이름 매핑을 지정합니까? (0) | 2020.02.07 |
[RUBY-ON-RAILS] 레일 3 루비 : 클라이언트에 레일을 통해 스트리밍 데이터 (0) | 2020.02.07 |