使用Ruby将数字转换为单词?

如何将数字转换为ruby中的单词?

我知道某处有一块gem。 试图在没有gem的情况下实现它。 我只需要用英语中的数字来表示整数。 发现这个,但它非常凌乱。 如果您对如何实现更清洁易读的解决方案有任何想法,请分享。

Ruby – convert number to english word

这是我一直在努力的方面。 但是在实施量表时遇到一些问题。 代码仍然是一团糟。 我希望它在正常运行时更具可读性。

class Numberswords def in_words(n) words_hash = {0=>"zero",1=>"one",2=>"two",3=>"three",4=>"four",5=>"five",6=>"six",7=>"seven",8=>"eight",9=>"nine", 10=>"ten",11=>"eleven",12=>"twelve",13=>"thirteen",14=>"fourteen",15=>"fifteen",16=>"sixteen", 17=>"seventeen", 18=>"eighteen",19=>"nineteen", 20=>"twenty",30=>"thirty",40=>"forty",50=>"fifty",60=>"sixty",70=>"seventy",80=>"eighty",90=>"ninety"} scale = [000=>"",1000=>"thousand",1000000=>" million",1000000000=>" billion",1000000000000=>" trillion", 1000000000000000=>" quadrillion"] if words_hash.has_key?(n) words_hash[n] #still working on this middle part. Anything above 999 will not work elsif n>= 1000 print n.to_s.scan(/.{1,3}/) do |number| print number end #print value = n.to_s.reverse.scan(/.{1,3}/).inject([]) { |first_part,second_part| first_part << (second_part == "000" ? "" : second_part.reverse.to_i.in_words) } #(value.each_with_index.map { |first_part,second_part| first_part == "" ? "" : first_part + scale[second_part] }-[""]).reverse.join(" ") elsif n "hundred" }) ([(n%100 < 20 ? n%100 : n.to_s[2].to_i), n.to_s[1].to_i*10, 100, n.to_s[0].to_i]-[0]-[10]) .reverse.map { |num| words_hash[num] }.join(" ") end end end #test code test = Numberswords.new print test.in_words(200) 

我对此有所了解

 def in_words(int) numbers_to_name = { 1000000 => "million", 1000 => "thousand", 100 => "hundred", 90 => "ninety", 80 => "eighty", 70 => "seventy", 60 => "sixty", 50 => "fifty", 40 => "forty", 30 => "thirty", 20 => "twenty", 19=>"nineteen", 18=>"eighteen", 17=>"seventeen", 16=>"sixteen", 15=>"fifteen", 14=>"fourteen", 13=>"thirteen", 12=>"twelve", 11 => "eleven", 10 => "ten", 9 => "nine", 8 => "eight", 7 => "seven", 6 => "six", 5 => "five", 4 => "four", 3 => "three", 2 => "two", 1 => "one" } str = "" numbers_to_name.each do |num, name| if int == 0 return str elsif int.to_s.length == 1 && int/num > 0 return str + "#{name}" elsif int < 100 && int/num > 0 return str + "#{name}" if int%num == 0 return str + "#{name} " + in_words(int%num) elsif int/num > 0 return str + in_words(int/num) + " #{name} " + in_words(int%num) end end end puts in_words(4) == "four" puts in_words(27) == "twenty seven" puts in_words(102) == "one hundred two" puts in_words(38_079) == "thirty eight thousand seventy nine" puts in_words(82102713) == "eighty two million one hundred two thousand seven hundred thirteen" 

你认为’人性化’吗?

https://github.com/radar/humanize

您也可以使用to_words gem。

这个Gem将整数转换为单词。

例如

 1.to_words # one , 100.to_words # one hundred , 101.to_words # one hundred and one 

它还转换负数。

简单的答案使用humanizegem,你会得到理想的输出

 require 'humanize' 1.humanize #=> 'one' 345.humanize #=> 'three hundred and forty-five' 1723323.humanize #=> 'one million, seven hundred and twenty-three thousand, three hundred and twenty-three' 

如果您在rails中使用它,可以直接使用它

我可以看到你在寻找什么,你可能希望查看这个StackOverflowpost: 数字到英文单词转换轨道

总结如下:

不,你必须自己写一个function。 最接近你想要的是number_to_human,但是不能将1转换为One。

以下是一些可能有用的url:

http://codesnippets.joyent.com/posts/show/447 http://raveendran.wordpress.com/2009/05/29/ruby-convert-number-to-english-word/ http://deveiate.org /项目/语言学/

我不太确定,如果这适合你。 可以像这样调用方法。

 n2w(33123) {|i| puts i unless i.to_s.empty?} 

这是方法(我没有完全测试过。我认为它的工作量高达百万。代码很难看,有很多重新分解的空间。)

 def n2w(n) words_hash = {0=>"zero",1=>"one",2=>"two",3=>"three",4=>"four",5=>"five",6=>"six",7=>"seven",8=>"eight",9=>"nine", 10=>"ten",11=>"eleven",12=>"twelve",13=>"thirteen",14=>"fourteen",15=>"fifteen",16=>"sixteen", 17=>"seventeen", 18=>"eighteen",19=>"nineteen", 20=>"twenty",30=>"thirty",40=>"forty",50=>"fifty",60=>"sixty",70=>"seventy",80=>"eighty",90=>"ninety"} scale = {3=>"hundred",4 =>"thousand",6=>"million",9=>"billion"} if words_hash.has_key?n yield words_hash[n] else ns = n.to_s.split(//) while ns.size > 0 if ns.size == 2 yield("and") yield words_hash[(ns.join.to_i) - (ns.join.to_i)%10] ns.shift end if ns.size > 4 yield(words_hash[(ns[0,2].join.to_i) - (ns[0,2].join.to_i) % 10]) else yield(words_hash[ns[0].to_i]) end yield(scale[ns.size]) ns.shift end end end 
 def subhundred number ones = %w{zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen} tens = %w{zero ten twenty thirty **forty** fifty sixty seventy eighty ninety} subhundred = number % 100 return [ones[subhundred]] if subhundred < 20 return [tens[subhundred / 10]] if subhundred % 10 == 0 return [tens[subhundred / 10], ones[subhundred % 10]] end def subthousand number hundreds = (number % 1000) / 100 tens = number % 100 s = [] s = subhundred(hundreds) + ["hundred"] unless hundreds == 0 s = s + ["and"] unless hundreds == 0 or tens == 0 s = s + [subhundred(tens)] unless tens == 0 end def decimals number return [] unless number.to_s['.'] digits = number.to_s.split('.')[1].split('').reverse digits = digits.drop_while {|d| d.to_i == 0} . reverse digits = digits.map {|d| subhundred d.to_i} . flatten digits.empty? ? [] : ["and cents"] + digits end def words_from_numbers number steps = [""] + %w{thousand million billion trillion quadrillion quintillion sextillion} result = [] n = number.to_i steps.each do |step| x = n % 1000 unit = (step == "") ? [] : [step] result = subthousand(x) + unit + result unless x == 0 n = n / 1000 end result = ["zero"] if result.empty? result = result + decimals(number) result.join(' ').strip end def words_from_numbers(number) ApplicationHelper.words_from_numbers(number) end 

以下是我选择解决问题的方法,使用几种较小的方法来处理解决方案。 希望这可以帮助!

 module WordsModule def in_words if self == 0 return "zero" elsif self > 999_999_999_999 return trillions(self) elsif self > 999_999_999 return billions(self) elsif self > 999_999 return millions(self) elsif self > 999 return thousands(self) elsif self > 99 return hundreds(self) elsif self > 9 return "#{tens(self)}" else return "#{single(self)}" end end private def trillions(number) if number.between?(100_000_000_000_000, 999_999_999_999_999) if number % 1_000_000_000_000 == 0 "#{hundreds(number/1_000_000_000_000)} trillion" else "#{hundreds(number/1_000_000_000_000)} trillion #{billions(number%1_000_000_000_000)}" end elsif number.between?(10_000_000_000_000, 99_999_999_999_999) if number % 1_000_000_000_000 == 0 "#{tens(number/1_000_000_000_000)} trillion" else "#{tens(number/1_000_000_000_000)} trillion #{billions(number%1_000_000_000_000)}" end elsif number.between?(1_000_000_000_000, 9_999_999_999_999) if number % 1_000_000_000_000 == 0 "#{single(number/1_000_000_000_000)} trillion" else "#{single(number/1_000_000_000_000)} trillion #{billions(number%1_000_000_000_000)}" end else millions(number) end end def billions(number) if number.between?(100_000_000_000, 999_999_999_999) if number % 1_000_000_000 == 0 "#{hundreds(number/1_000_000_000)} billion" else "#{hundreds(number/1_000_000_000)} billion #{millions(number%1_000_000_000)}" end elsif number.between?(10_000_000_000, 99_999_999_999) if number % 1_000_000_000 == 0 "#{tens(number/1_000_000_000)} billion" else "#{tens(number/1_000_000_000)} billion #{millions(number%1_000_000_000)}" end elsif number.between?(1_000_000_000, 9_999_999_999) if number % 1_000_000_000 == 0 "#{single(number/1_000_000_000)} billion" else "#{single(number/1_000_000_000)} billion #{millions(number%1_000_000_000)}" end else millions(number) end end def millions(number) if number.between?(100_000_000, 999_999_999) if number % 1_000_000 == 0 "#{hundreds(number/1_000_000)} million" else "#{hundreds(number/1_000_000)} million #{thousands(number%1_000_000)}" end elsif number.between?(10_000_000, 99_999_999) if number % 1_000_000 == 0 "#{tens(number/1_000_000)} million" else "#{tens(number/1_000_000)} million #{thousands(number%1_000_000)}" end elsif number.between?(1_000_000, 9_999_999) if number % 1_000_000 == 0 "#{single(number/1_000_000)} million" else "#{single(number/1_000_000)} million #{thousands(number%1_000_000)}" end else thousands(number) end end def thousands(number) if number.between?(100_000, 999_999) if number % 1000 == 0 "#{hundreds(number/1000)} thousand" else "#{hundreds(number/1000)} thousand #{hundreds(number%1000)}" end elsif number.between?(10_000, 99_999) if number % 1000 == 0 "#{tens(number/1000)} thousand" else "#{tens(number/1000)} thousand #{hundreds(number%1000)}" end elsif number.between?(1_000, 9_999) if number % 1000 == 0 "#{single(number/1000)} thousand" else "#{single(number/1000)} thousand #{hundreds(number%1000)}" end else hundreds(number) end end def hundreds(number) if number % 100 == 0 "#{single(number/100)} hundred" elsif number.between?(101, 999) "#{single(number/100)} hundred #{tens(number%100)}" else tens(number) end end def tens(number) teens = { 11 => "eleven", 12 => "twelve", 13 => "thirteen", 14 => "fourteen", 15 => "fifteen", 16 => "sixteen", 17 => "seventeen", 18 => "eighteen", 19 => "nineteen" } tens = { 1 => "ten", 2 => "twenty", 3 => "thirty", 4 => "forty", 5 => "fifty", 6 => "sixty", 7 => "seventy", 8 => "eighty", 9 => "ninety" } if number.between?(11, 19) teens[number] elsif number % 10 == 0 tens[number/10] elsif number.between?(21, 99) "#{tens[number/10]} #{single(number%10)}" else single(number) end end def single(number) single_digit_hash = { 1 => "one", 2 => "two", 3 => "three", 4 => "four", 5 => "five", 6 => "six", 7 => "seven", 8 => "eight", 9 => "nine" } single_digit_hash[number] end end class Integer include WordsModule end