2014-07-27 20 views
30

Để lập trình web, các số có dạng chuỗi. nhưng to_i sẽ chuyển đổi "5abc" thành 5"abc" thành 0, cả hai câu trả lời sai. Để bắt này, tôi đã viết:Chuyển đổi chuỗi thành số nguyên (hoặc số không)

def number_or_nil(s) 
    number = s.to_i 
    number = nil if (number.to_s != s) 
    return number 
end 

Có một gọn gàng, cách hơn Ruby-tự nhiên của việc hoàn thành chuyển đổi này và phát hiện rằng chuỗi đã không được sử dụng như một số?

+0

''5'' phải là '5' hoặc' nil'? –

+0

Câu hỏi không rõ ràng. Có gì sai với 'to_i'? "Chuyển đổi này" là gì? – sawa

+0

nil là những gì tôi mong đợi, mặc dù tôi có thể sống với 5. –

Trả lời

56

Sử dụng Integer (string)

Nó sẽ nâng cao một lỗi ArgumentError nếu chuỗi không thể chuyển đổi thành một số nguyên.

Integer('5abc') #=> ArgumentError: invalid value for Integer(): "5abc" 
Integer('5') #=> 5 

Bạn vẫn cần phương thức number_or_nil nếu bạn muốn hành vi là số không được trả về khi không thể chuyển đổi chuỗi.

def number_or_nil(string) 
    Integer(string || '') 
rescue ArgumentError 
    nil 
end 

Bạn nên cẩn thận giải cứu khỏi một ngoại lệ cụ thể. Một giải cứu trần (chẳng hạn như "rescue nil") sẽ giải cứu từ bất kỳ lỗi nào thừa kế từ StandardError và có thể ảnh hưởng đến việc thực thi chương trình của bạn theo những cách bạn không mong đợi. Integer() sẽ tăng một ArgumentError, vì vậy hãy xác định điều đó.

Nếu bạn không muốn đối phó với trường hợp ngoại lệ và chỉ muốn có một phiên bản ngắn hơn của number_or_nil của bạn, bạn có thể tận dụng giá trị trả lại tiềm ẩn và viết nó như:

def number_or_nil(string) 
    num = string.to_i 
    num if num.to_s == string 
end 

number_or_nil '5' #=> 5 
number_or_nil '5abc' #=> nil 

này sẽ làm việc theo cách bạn mong đợi.

+3

Chỉ báo trước là 'Integer (nil)' tăng 'TypeError', vì vậy' Integer (string || '') 'là nhất quán hơn. – RocketR

+0

Điểm tốt @RocketR! –

+1

Tôi có thể tìm tài liệu (chính thức) cho 'Integer (string)' ở đâu? Theo như tôi có thể thấy không có đề cập đến nó trong tài liệu chính thức của [Integy 'Integer'] (http://ruby-doc.org/core-2.2.3/Integer.html). – apepper

0

Sử dụng một regex đơn giản để kiểm tra str là một số nguyên.

def number_or_nil(str) 
    str.to_i if str[/^-?\d+$/] and str.line.size == 1 
end 
+0

Vì đầu vào đến từ web, bạn nên thay đổi câu trả lời của bạn để mong đợi nhiều nội dung dòng. str.to_i nếu str [/ \ A \ d + \ z /] –

+0

Số nguyên âm, khoảng trắng? –

+0

Đã sửa lỗi. Tôi kiểm tra hy vọng các quy tắc nghiêm ngặt cho các số nguyên, không có khoảng trắng, không có dòng mới. – hakcho

Các vấn đề liên quan