ruby number to human-readable string conversion
I need to have a list with id's for each list item being #one
, #two
etc.
Is this the most efficient way or am I missing an in built ruby function here?
-num_array = ["one", "two", "three", "four", "five", "six", "seven"]
-navigation[:primary_level].each_with_index do |primar开发者_StackOverflowy_item, idx|
%li{ :id => "#{num_array[idx]}"}
The humanize gem converts digits into words.
Outside of using the humanize gem, using a hash would be way easier than the array stuff:
lookup = {"one" => 1, "two" => 2, "three" => 3, etc...}
text = "two"
num = lookup[text]
I'm sure this goes well beyond what you need, but there's code to do that at Rosetta Code
Here's my attempt at a solution in Ruby. It is likely suboptimal and has not been checked for correctness.
<<documentation
Converting Numbers to Human Readable Pretty Print Strings
General Description
===================
- Divide the number into groups of three
- e.g. turn 87012940 -> 87,012,940
- Parse each individual group
- e.g. 940 -> "nine hundred forty"
- Only parse the rightmost two numbers
- 0 -> 12: special cases; use hardcoded switch statements
- e.g. "one, two, three ... ten, eleven, twelve"
- 13 -> 19: same hardcoded switch statement + a "-teen" prefix
- e.g. "thirteen, fourteen, fifteen ... nineteen"
- 20 -> 99:
- Parse left digit and return according to the following rule:
- "twenty, thirty, forty, fifty, sixty ... ninety"
- Return the simple name of the right digit:
- "one, two, nine"
- special case: zero -> ""
- This is because the hundredth's place follows a simple prefix rule
- e.g. one-hundred, two-hundred, three-hundred ... nine-hundred
- special case: zero -> " "
- Add place modifiers according to each group's placement
- e.g. the middle '012' -> "twelve thousand"
- Concatenate all and return as solution
Algorithm (slightly modified)
=============================
Modifications
-------------
- No need to divide number into groups of three; simply parse right-to-left one at a time
- When finished processing one group, insert the result leftmost into our final solution string
documentation
def convert(num)
return 'zero' if (num == 0)
answer = ''
places = ['',
'thousand ',
'million ',
'billion ',
'trillion ',
'quadrillion ',
'quintillion ']
place = 0
loop do
break if num == 0
# Get the rightmost group of three
first_three_digits = num % 1000
# Truncate the original number by those three digits
num /= 1000
answer.insert(0, convert_group_of_three(first_three_digits) + places[place])
place += 1
end
answer.strip!
end
def convert_group_of_three(num)
str = ''
# Zero returns an empty string
special_cases = ['', 'one ', 'two ', 'three ', 'four ', 'five ', 'six ', 'seven ', 'eight ', 'nine ', 'ten ',
'eleven ', 'twelve ', 'thirteen ', 'fourteen ', 'fifteen ', 'sixteen ', 'seventeen ', 'eighteen ', 'nineteen ']
return special_cases[num % 100] if (0 .. special_cases.length - 1).include? (num % 100)
# If not in special cases, num must be at least a two digit number
# Pull the first digit
first_digit = num % 10
num /= 10
str.insert(0, special_cases[first_digit])
# Pull the second digit
second_digit = num % 10
num /= 10
second_digit_str = ''
case second_digit
when 2
second_digit_str = 'twenty '
when 3
second_digit_str = 'thirty '
when 4
second_digit_str = 'forty '
when 5
second_digit_str = 'fifty '
when 6
second_digit_str = 'sixty '
when 7
second_digit_str = 'seventy '
when 8
second_digit_str = 'eighty '
when 9
second_digit_str = 'ninety '
end
str.insert(0, second_digit_str)
# If there is a third digit
if num > 0
third_digit = num % 10
str.insert(0, special_cases[third_digit] + 'hundred ')
end
str
end
p convert(2389475623984756)
Output:
"two quadrillion three hundred eighty nine trillion four hundred seventy five billion six hundred twenty three million nine hundred eighty four thousand seven hundred fifty six"
精彩评论