在没有辅助方法的情况下计算Ruby中的序数?

时间:2015-04-03 19:05:55

标签: ruby

我需要弄清楚如何计算Ruby中的序数,除了第13,113,113等边缘情况外,我几乎有一个解决方案。

puts "Enter a number:"

n = gets.delete(',').chomp.to_i


rank =  n % 10   


ordinal =

if rank == 1 
  n.to_s + 'st'
elsif rank == 2 
 n.to_s + 'nd'
elsif rank == 3 
 n.to_s + 'rd'
else
 n.to_s + 'th'
end


puts "That's the #{ordinal} item!"

3 个答案:

答案 0 :(得分:3)

您可以复制来自active_support / inflector

的那个
def ordinal(number)
  abs_number = number.to_i.abs

  if (11..13).include?(abs_number % 100)
    "th"
  else
    case abs_number % 10
      when 1; "st"
      when 2; "nd"
      when 3; "rd"
      else    "th"
    end
  end
end

答案 1 :(得分:0)

我认为将字符串转换为整数没有意义。没有必要并将其保持为字符串提供了更大的灵活性,如下面的最后两个例子所示。

ordinal(gets.chomp)

def ordinal(str)
  return nil if str.empty?
  (return str + "th") if ('11'..'13').cover?(str[-2,2])
  str +
  case str[-1]
  when "1" then "st"
  when "2" then "nd"
  when "3" then "rd"
  else "th"
  end
end

ordinal(         "0") #=>          "0th" 
ordinal(         "1") #=>          "1st" 
ordinal(         "2") #=>          "2nd" 
ordinal(         "3") #=>          "3rd" 
ordinal(         "4") #=>          "4th" 
ordinal(        "10") #=>         "10th" 
ordinal(        "11") #=>         "11th" 
ordinal(       "-12") #=>        "-12th" 
ordinal(        "40") #=>         "40th" 
ordinal(        "41") #=>         "41st" 
ordinal(        "42") #=>         "42nd" 
ordinal(        "43") #=>         "43rd" 
ordinal(        "44") #=>         "44th" 
ordinal(       "100") #=>        "100th" 
ordinal(      "-100") #=>       "-100th" 
ordinal(       "152") #=>        "152nd" 
ordinal(      "1523") #=>       "1523rd" 
ordinal(    "-15233") #=>     "-15233rd" 
ordinal(   "-15,233") #=>    "-15,233rd" 
ordinal("the 15,233") #=> "the 15,233rd" 

答案 2 :(得分:0)

您也可以使用正则表达式。

    require 'pp'

    puts "Enter a number:\n"
    number = gets.chomp

    def make_ordinal( number )
      ordinal = num_string( number ) + "th" unless num_string( number ) =~ /(\A[1,2,3]\z|01|02|03)/
      ordinal ||= edge_case( number )
    end

    def edge_case( number )
      num = num_string( number )
      case
      when num.match(/(\A[1]\z|01)/)
        num_string( number ) + "st"
      when num.match(/(\A[2]\z|02)/)
        num_string( number ) + "nd"
      when num.match(/(\A[3]\z|03)/)
        num_string( number ) + "rd"
      end
    end

    def num_string( number )
      return number.to_s
    end

    pp make_ordinal( number )