How to convert numbers to words in ruby?
I know there is a gem somewhere. Trying to implement it without a gem. I just need the numbers to words in English for integ
I am not quite sure, if this works for you. Method can be called like this.
n2w(33123) {|i| puts i unless i.to_s.empty?}
Here is the method ( I have not tested it fully. I think it works upto million. Code is ugly, there is a lot of room for re-factoring. )
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
I can see what you're looking for, and you may wish to check out this StackOverflow post: Number to English Word Conversion Rails
Here it is in summary:
No, you have to write a function yourself. The closest thing to what you want is number_to_human, but that does not convert 1 to One.
Here are some URLs that may be helpful:
http://codesnippets.joyent.com/posts/show/447 http://raveendran.wordpress.com/2009/05/29/ruby-convert-number-to-english-word/ http://deveiate.org/projects/Linguistics/
Here is how I chose to solve the problem, using several smaller methods to handle the solution. Hope this helps!
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
Have you consider 'humanize' ?
https://github.com/radar/humanize
My take on this
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"
Simple answer use humanize gem and you will get desired output
Install it directly
gem install humanize
Or add it to your Gemfile
gem 'humanize'
And you can use it
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'
If you are using this in rails you can directly use this
NOTE: As mentioned by sren in the comments below. The humanize method provided by ActiveSupport
is different than the gem humanize