【问题标题】:ruby number to human-readable string conversion红宝石数字到人类可读的字符串转换
【发布时间】:2014-11-23 06:51:03
【问题描述】:

我需要一个列表,其中每个列表项的 id 为 #one#two 等。 这是最有效的方法还是我在这里缺少内置的 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]}"}

【问题讨论】:

  • 那条评论真的把我扔了,我终于通过找到caiustheory.com/ruby-shortcuts 找到了你所指的内容——发现它与“红宝石数字到人类可读的字符串转换”无关
  • %w() 用于数组生成。你可以写%w(one two three four five six seven) 不带引号。但它不会将数字转换为字符串。

标签: ruby numbers


【解决方案1】:

humanize gem 将数字转换为单词。

【讨论】:

  • 很好 - 如果我需要,这对我来说似乎是最适合这项工作的工具。
【解决方案2】:

在使用humanize gem 之外,使用哈希比使用数组更容易:

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

【讨论】:

    【解决方案3】:

    我确信这远远超出了您的需要,但在 Rosetta Code 有代码可以做到这一点

    【讨论】:

    • 酷 - 如果我需要大规模使用它,我会使用它。从这个答案中,我确信答案是“不,本机 ruby​​ 类中尚不提供此功能”。谢谢
    【解决方案4】:

    这是我对 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"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 2014-02-11
      • 2011-01-21
      • 1970-01-01
      • 2013-04-04
      • 2021-07-08
      相关资源
      最近更新 更多