使用 Ruby 将数字转换为单词?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19445003/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using Ruby convert numbers to words?
提问by hken27
How to convert numbers to words in ruby?
如何将数字转换为 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 integers. Found this but it is very messy. If you have any idea on how to implement a cleaner easier to read solution please share.
我知道某处有一颗宝石。试图在没有 gem 的情况下实现它。我只需要数字到英文单词的整数。找到了这个,但是很乱。如果您对如何实现更简洁易读的解决方案有任何想法,请分享。
http://raveendran.wordpress.com/2009/05/29/ruby-convert-number-to-english-word/
http://raveendran.wordpress.com/2009/05/29/ruby-convert-number-to-english-word/
Here is what I have been working on. But having some problem implementing the scales. The code is still a mess. I hope to make it more readable when it functions properly.
这是我一直在研究的内容。但是在实施秤时遇到了一些问题。代码还是一团糟。我希望在它正常运行时使其更具可读性。
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 <= 99
return [words_hash[n - n%10],words_hash[n%10]].join(" ")
else
words_hash.merge!({ 100=>"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)
回答by NoNonsense
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"
回答by rhernando
回答by taimur akhtar
回答by Deepak Mahakale
Simple answer use humanizegem and you will get desired output
简单的答案使用humanizegem,您将获得所需的输出
Install it directly
直接安装
gem install humanize
Or add it to your Gemfile
或者将它添加到您的 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
如果你在 Rails 中使用它,你可以直接使用它
NOTE: As mentioned by srenin the comments below. The humanizemethod provided by ActiveSupportis different than the gem humanize
回答by Richard Peck
I can see what you're looking for, and you may wish to check out this StackOverflow post: Number to English Word Conversion Rails
我可以看到你在找什么,你可能希望查看这篇 StackOverflow 帖子: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/447http://raveendran.wordpress.com/2009/05/29/ruby-convert-number-to-english-word/http://deveiate.org/projects/Linguistics/
不,你必须自己写一个函数。最接近您想要的是 number_to_human,但这不会将 1 转换为 1。
以下是一些可能有用的 URL:
http://codesnippets.joyent.com/posts/show/447 http://raveendran.wordpress.com/2009/05/29/ruby-convert-number-to-english-word/ http://deveiate.org /项目/语言学/
回答by Bala
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
回答by dsn raghavendra rao
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
回答by David McAfee
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

