Kiểm tra nếu một biến là một số nguyên


137

Rails 3 hoặc Ruby có tích hợp sẵn để kiểm tra xem một biến có phải là số nguyên không?

Ví dụ,

1.is_an_int #=> true
"dadadad@asdasd.net".is_an_int #=> false?


1
Thay vì quan tâm xem một biến có phải là số nguyên hay không, bạn nên kiểm tra xem biến đó có đáp ứng hay không to_i. Đó là một phần trong "gõ vịt" của Ruby: Nếu nó có thể hoạt động như một số nguyên, hãy coi nó như một số nguyên.
Tin Man

4
@ The Tin Man: Không hoàn toàn. "xin chào" .to_i trả về 0 có thể không như bạn mong đợi.
EinLama

1
@AnApprentice Để biết thông tin của bạn, kind_of?là bí danh is_a?.
Jacob Relkin

3
@JacobRelkin is_a?hơi khác một chút; nó hỏi nếu đối tượng của một thể hiện của một lớp cụ thể; kind_of?hỏi nếu nó là một thể hiện hoặc con của một lớp cụ thể. fido.is_a? Doglà đúng; fido.kind_of? Animallà đúng, ví dụ.
Tom Harrison

Câu trả lời:


274

Bạn có thể sử dụng is_a?phương pháp

>> 1.is_a? Integer
=> true
>> "dadadad@asdasd.net".is_a? Integer
=> false
>> nil.is_a? Integer
=> false

2
Điều đó thật ngầu. làm việc đó để xác nhận địa chỉ email đến?
AnApprentice

65
@AnApprentice Kể từ khi xác thực địa chỉ email là một phần của câu hỏi?
Jacob Relkin

4
điều này sẽ không hoạt động nếu số đến trong một chuỗi như "11111111"
Ricbermo

nhìn bên dưới Integer(obj) rescue false Điều này sẽ không hoạt động cho "1" nếu bạn muốn kiểm tra xem nó có chuyển đổi không
mc.

4
@Ricbermo "1111111" là một Chuỗi. Một chuỗi có thể chuyển đổi thành và Integer.
Sqeaky

50

Nếu bạn muốn biết liệu một đối tượng là một Integer thứ gì đó có thể được chuyển đổi một cách có ý nghĩa thành một Số nguyên (KHÔNG bao gồm những thứ như "hello", to_isẽ chuyển đổi thành 0):

result = Integer(obj) rescue false

2
Có lẽ tôi chỉ là một người mới, nhưng điều chỉnh này sẽ giúp tôi. result = Integer (obj) cứu sai.
John Curry

@JohnCurry, vui lòng chỉnh sửa câu trả lời nếu bạn có thể cải thiện nó. Đó là cách SO hoạt động.
Alex D

2
Tôi đã làm, nó đã bị từ chối. "Chỉnh sửa này đi lệch khỏi mục đích ban đầu của bài viết" Nhưng bất kể, cảm ơn bạn đã trả lời, nó đã giúp tôi giải quyết vấn đề của mình!
John Curry

7
Số nguyên ('08 ') sẽ không thành công do chuỗi được hiểu là bát phân, Số nguyên ('08', 10) hoạt động tốt. Chỉ trong trường hợp.
Jong Bor Lee

1
Không chắc chắn nếu Integer(2.5) => 2luôn luôn là một chuyển đổi có ý nghĩa.
mkataja

29

Sử dụng biểu thức chính quy trên chuỗi:

def is_numeric?(obj) 
   obj.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true
end

Nếu bạn muốn kiểm tra xem một biến có thuộc loại nhất định hay không, bạn chỉ cần sử dụng kind_of?:

1.kind_of? Integer #true
(1.5).kind_of? Float #true
is_numeric? "545"  #true
is_numeric? "2aa"  #false

Đây chính xác là những gì tôi đang tìm kiếm is_numeric?
việc

Tôi nghĩ rằng điều này là gần, nhưng không chính xác. Chẳng hạn, nó sẽ thất bại trong ".34". Vấn đề, tôi nghĩ, là trong \d+?các ?quy định cụ thể một trận đấu không tham lam, trong khi bạn có thể muốn có một trận đấu không bắt buộc. Thay đổi \d+?thành \d*có thể sửa nó, nhưng tôi muốn chạy nó thông qua một bộ thử nghiệm để chắc chắn. Điều này cũng sẽ không khớp với ký hiệu hex hoặc số mũ, nhưng tôi chắc chắn rằng điều đó tốt cho các trường hợp sử dụng nhất định.
Jeff

1
Tại sao không chỉ để sử dụng regrec này : \A\d+\z?
NARKOZ

1
So sánh với Integer(obj) rescue falsemã từ @ alex-d bên dưới; regrec rất khó đọc và không rõ ràng trong ý định của nó. Cả hai công việc, tôi đã đi đến câu hỏi này trong một nỗ lực để sửa chữa một regrec được xây dựng kém mà không phải lúc nào cũng hoạt động :-)
Tom Harrison

17

Nếu bạn không chắc chắn về loại biến (có thể là một chuỗi các ký tự số), hãy nói rằng đó là số thẻ tín dụng được truyền vào các thông số, vì vậy ban đầu nó sẽ là một chuỗi nhưng bạn muốn chắc chắn rằng nó không ' Tôi có bất kỳ ký tự chữ nào trong đó, tôi sẽ sử dụng phương pháp này:

    def is_number?(obj)
        obj.to_s == obj.to_i.to_s
    end

    is_number? "123fh" # false
    is_number? "12345" # true

@Benny chỉ ra một sự giám sát của phương pháp này, hãy ghi nhớ điều này:

is_number? "01" # false. oops!

cảm ơn, bạn tiết kiệm trong ngày của tôi Đối với bất cứ ai cần kiểm tra xem nó có nổi hay không có thể thay đổi trực tiếp obj.to_s == obj.to_f.to_sgiống như trong trường hợp của tôi.
ksugiarto

Edmund thật thông minh! 🙌
siwalikm

Tuyệt vời, tôi thích cái này hơn Integer ('123fh') và ngoại lệ cứu hộ.
zw963

6

Bạn có thể sử dụng ba bằng nhau.

if Integer === 21 
    puts "21 is Integer"
end

5

var.is_a? Class(trong trường hợp của bạn var.is_a? Integer:); có thể phù hợp với hóa đơn. Hoặc ở đó Integer(var), nơi nó sẽ ném một ngoại lệ nếu nó không thể phân tích cú pháp.


3

Một cách "gõ vịt" hơn là sử dụng respond_to?cách này cũng có thể sử dụng các lớp "giống như số nguyên" hoặc "giống như chuỗi"

if(s.respond_to?(:match) && s.match(".com")){
  puts "It's a .com"
else
  puts "It's not"
end

2

Trong trường hợp bạn không cần chuyển đổi giá trị 0, tôi tìm các phương thức to_ito_fcực kỳ hữu ích vì chúng sẽ chuyển đổi chuỗi thành giá trị 0 (nếu không chuyển đổi hoặc bằng 0) hoặc thực tế Integerhoặc Floatgiá trị.

"0014.56".to_i # => 14
"0014.56".to_f # => 14.56
"0.0".to_f # => 0.0
"not_an_int".to_f # 0
"not_a_float".to_f # 0.0

"0014.56".to_f ? "I'm a float" : "I'm not a float or the 0.0 float" 
# => I'm a float
"not a float" ? "I'm a float" : "I'm not a float or the 0.0 float" 
# => "I'm not a float or the 0.0 float"

EDIT2: hãy cẩn thận, 0giá trị số nguyên không phải là chim ưng, đó là sự thật ( !!0 #=> true) (cảm ơn @prettycoder)

BIÊN TẬP

Ah chỉ phát hiện ra các trường hợp đen tối ... dường như chỉ xảy ra nếu số ở vị trí đầu tiên mặc dù

"12blah".to_i => 12

0 là sự thật trong ruby!
prettycoder

1
@prettycoder cảm ơn vì đã ngẩng cao đầu, tôi sẽ khắc phục điều này ngay lập tức trong câu trả lời
Cyril Duchon-Doris

1

Để tận dụng câu trả lời của Alex D , hãy sử dụng các sàng lọc :

module CoreExtensions
  module Integerable
    refine String do
      def integer?
        Integer(self)
      rescue ArgumentError
        false
      else
        true
      end
    end
  end
end

Sau đó, trong lớp bạn:

require 'core_ext/string/integerable'

class MyClass
  using CoreExtensions::Integerable

  def method
    'my_string'.integer?
  end
end

0

Tôi đã có một vấn đề tương tự trước khi cố gắng xác định xem một cái gì đó là một chuỗi hoặc bất kỳ loại số nào. Tôi đã thử sử dụng một biểu thức thông thường, nhưng điều đó không đáng tin cậy cho trường hợp sử dụng của tôi. Thay vào đó, bạn có thể kiểm tra lớp của biến để xem nó có phải là hậu duệ của lớp Số không.

if column.class < Numeric
  number_to_currency(column)
else
  column.html_safe
end

Trong tình huống này, bạn cũng có thể thay thế cho bất kỳ hậu duệ số nào: BigDecimal, Date :: Infinity, Integer, Fixnum, Float, Bignum, Rational, Complex


-1

Có lẽ bạn đang tìm kiếm một cái gì đó như thế này:

Chấp nhận "2.0 hoặc 2.0 làm INT nhưng từ chối 2.1 và" 2.1 "

num = 2.0

nếu num.is_a? Chuỗi num = Float (num) cứu kết thúc sai

new_num = Số nguyên (num) cứu sai

đặt num

đặt new_num

đặt num == new_num

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.