I need a function, is_an_integer, where
\"12\".is_an_integer? returns true
\"blah\".is_an_integer? returns false
how can i do this in ruby? i would write a regex but im assuming there is a helper for this that i am not aware of
I need a function, is_an_integer, where
\"12\".is_an_integer? returns true
\"blah\".is_an_integer? returns false
how can i do this in ruby? i would write a regex but im assuming there is a helper for this that i am not aware of
You can use regular expressions. Here is the function with @janm\'s suggestions.
class String
def is_i?
!!(self =~ /\\A[-+]?[0-9]+\\z/)
end
end
An edited version according to comment from @wich:
class String
def is_i?
/\\A[-+]?\\d+\\z/ === self
end
end
In case you only need to check positive numbers
if !/\\A\\d+\\z/.match(string_to_check)
#Is not a positive number
else
#Is all good ..continue
end
Well, here\'s the easy way:
class String
def is_integer?
self.to_i.to_s == self
end
end
>> \"12\".is_integer?
=> true
>> \"blah\".is_integer?
=> false
EDIT: I don\'t agree with the solutions that provoke an exception to convert the string - exceptions are not control flow, and you might as well do it the right way. That said, my solution above doesn\'t deal with non-base-10 integers. So here\'s the way to do with without resorting to exceptions:
class String
def integer?
[ # In descending order of likeliness:
/^[-+]?[1-9]([0-9]*)?$/, # decimal
/^0[0-7]+$/, # octal
/^0x[0-9A-Fa-f]+$/, # hexadecimal
/^0b[01]+$/ # binary
].each do |match_pattern|
return true if self =~ match_pattern
end
return false
end
end
You can use Integer(str)
and see if it raises:
def is_num?(str)
!!Integer(str, 10)
rescue ArgumentError, TypeError
false
end
Addendum: It should be pointed out that while this does return true for \"01\"
, it does not for \"09\"
, simply because 09
would not be a valid integer literal.
Addendum to addendum: Fixed this by changing Integer(str)
to Integer(str, 10)
, as per @jason-axelson\'s comment.
\"12\".match(/^(\\d)+$/) # true
\"1.2\".match(/^(\\d)+$/) # false
\"dfs2\".match(/^(\\d)+$/) # false
\"13422\".match(/^(\\d)+$/) # true
You can do a one liner:
str = ...
int = Integer(str) rescue nil
if int
int.times {|i| p i}
end
or even
int = Integer(str) rescue false
Depending on what you are trying to do you can also directly use a begin end block with rescue clause:
begin
str = ...
i = Integer(str)
i.times do |j|
puts j
end
rescue ArgumentError
puts \"Not an int, doing something else\"
end
class String
def integer?
Integer(self)
return true
rescue ArgumentError
return false
end
end
is_
. I find that silly on questionmark methods, I like \"04\".integer?
a lot better than \"foo\".is_integer?
.\"01\"
and such.The Best and Simple way is using Float
val = Float \"234\" rescue nil
Float \"234\" rescue nil #=> 234.0
Float \"abc\" rescue nil #=> nil
Float \"234abc\" rescue nil #=> nil
Float nil rescue nil #=> nil
Float \"\" rescue nil #=> nil
Integer
is also good but it will return 0
for Integer nil
I prefer:
config/initializers/string.rb
class String
def number?
Integer(self).is_a?(Integer)
rescue ArgumentError, TypeError
false
end
end
and then:
[218] pry(main)> \"123123123\".number?
=> true
[220] pry(main)> \"123 123 123\".gsub(/ /, \'\').number?
=> true
[222] pry(main)> \"123 123 123\".number?
=> false
or check phone number:
\"+34 123 456 789 2\".gsub(/ /, \'\').number?
personally I like the exception approach although I would make it a little terser.
class String
def integer?(str)
!!Integer(str) rescue false
end
end
However as others have already stated this doesn\'t work with Octal strings...
def isint(str)
return !!(str =~ /^[-+]?[1-9]([0-9]*)?$/)
end
A much simpler way could be
/(\\D+)/.match(\'1221\').nil? #=> true
/(\\D+)/.match(\'1a221\').nil? #=> false
/(\\D+)/.match(\'01221\').nil? #=> true
Might not be suitable for all cases but a simple
\"12\".to_i => 12
\"blah\".to_i => 0
might also do for some.
So if it\'s a number and not 0 it will return a number. If it returns 0 it\'s either a word string or 0.
Solution:
# /initializers/string.rb
class String
IntegerRegex = /^(\\d)+$/
def integer?
!!self.match(IntegerRegex)
end
end
# any_model_or_controller.rb
\'12345\'.integer? # true
\'asd34\'.integer? # false
Explanation:
/^(\\d)+$/
is regex expression for finding digits in any string. You can test your regex expressions and results at http://rubular.com/.IntegerRegex
to avoid unnecessary memory allocation everytime we use it in the method.integer?
is an interrogative method which should return true
or false
.match
is a method on string which matches the occurrences as per the given regex expression in argument and return the matched values or nil
.!!
converts the result of match
method into equivalent boolean.String
class is monkey patching, which doesn\'t change anything in existing String functionalities, but just adds another method named integer?
on any String object. Although explicit use of the case equality operator should be avoided, Regexp#===
looks very clean here:
def integer?(str)
/\\A[+-]?\\d+\\z/ === str
end
integer? \"123\" # true
integer? \"-123\" # true
integer? \"+123\" # true
integer? \"a123\" # false
integer? \"123b\" # false
integer? \"1\\n2\" # false
For more generalised cases (including numbers with decimal point), you can try the following method:
def number?(obj)
obj = obj.to_s unless obj.is_a? String
/\\A[+-]?\\d+(\\.[\\d]+)?\\z/.match(obj)
end
You can test this method in an irb session:
(irb)
>> number?(7)
=> #<MatchData \"7\" 1:nil>
>> !!number?(7)
=> true
>> number?(-Math::PI)
=> #<MatchData \"-3.141592653589793\" 1:\".141592653589793\">
>> !!number?(-Math::PI)
=> true
>> number?(\'hello world\')
=> nil
>> !!number?(\'hello world\')
=> false
For a detailed explanation of the regex involved here, check out this blog article :)
Expanding on @rado\'s answer above one could also use a ternary statement to force the return of true or false booleans without the use of double bangs. Granted, the double logical negation version is more terse, but probably harder to read for newcomers (like me).
class String
def is_i?
self =~ /\\A[-+]?[0-9]+\\z/ ? true : false
end
end
One liner in string.rb
def is_integer?; true if Integer(self) rescue false end
I\'m not sure if this was around when this question is asked but... For anyone that stumbles across this post, the simplest way is
var = \"12\"
var.is_a?(Integer) # returns false
var.is_a?(String) # returns true
var = 12
var.is_a?(Integer) # returns true
var.is_a?(String) # returns false
you can use is_a? method. for eg. 1.is_a? Integer will return true