Question

We have these strings:

  • "1/2"
  • "1"
  • "0.9"
  • "b"
  • "0,9"

How do I determine what type of data the strings are?

  • rational number
  • integer
  • float
  • not a number
  • not a number

in one piece of code?

Was it helpful?

Solution 3

Another way to do it using Kernels built in validator, just as an idea.

However, I think code that build its functionality on exceptions should be avoided, and the other solutions are probably preferred.

def determine_type x
 [:Integer, :Float, :Rational].each do |c|
   return c if send(c, x) rescue ArgumentError
 end
 return :String
end

p determine_type(1)     #=> :Integer
p determine_type('1')   #=> :Integer
p determine_type('1.0') #=> :Float
p determine_type('1/1') #=> :Rational
p determine_type('ccc') #=> :String

OTHER TIPS

{Rational => :to_r, Integer => :to_i, Float => :to_f }.each do |key, sym|
  ["1/2", "1", "0.9"].each do |item|
    puts "#{item} is #{key}" if item.send(sym).to_s == item
  end
end

#1/2 is a Rational
#1 is a Integer
#0.9 is a Float

for the "not a number" case, I think It's easy to enhance a bit

A more flexible and safer approach using regular expressions:

def parse(data)
  h = {
    "Float"    => /\A\d+\.\d+\Z/,
    "Integer"  => /\A\d+\Z/,
    "Rational" => /\A\d+\/\d+\Z/
  }

  h.each do |type, regex|
    return type if data.match regex
  end

  return "Not a number"
end

parse("1")   # => "Integer"
parse("1.2") # => "Float"
parse("1/2") # => "Rational"
parse("1,2") # => "Not a number"
parse("b")   # => "Not a number"

You could easily modify keys of the h hash to if you want it to return actual classes instead of strings.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top