ruby数字到人类可读的字符串转换

时间:2010-06-14 14:10:52

标签: ruby numbers

我需要为每个列表项#one#two等设置一个包含ID的列表。 这是最有效的方式还是我错过了内置的ruby函数?

-num_array = ["one", "two", "three", "four", "five", "six", "seven"]
-navigation[:primary_level].each_with_index do |primary_item, idx|
   %li{ :id => "#{num_array[idx]}"}

4 个答案:

答案 0 :(得分:4)

humanize gem将数字转换为单词。

答案 1 :(得分:2)

在使用humanize gem之外,使用hash会比数组更容易:

lookup = {"one" => 1, "two" => 2, "three" => 3, etc...}
text = "two"
num = lookup[text]

答案 2 :(得分:1)

我确信这远远超出了您的需求,但有代码可以在Rosetta Code

执行此操作

答案 3 :(得分:0)

这是我尝试使用Ruby的解决方案。它可能不是最理想的,并且没有检查其正确性。

<<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"