Converting String “2½” (two and a half) into 2.5

故事扮演 提交于 2020-02-19 09:41:07

问题


Right now I'm building a small app that imports data from a spreadsheet and due to the nature of the original entry, there is a string being read in that has values such as 8½, 2½, etc.

My goal with a simple function is to convert 2½ into float 2.5, for example.

I've tried the .to_f method but that has left me with a weird value of 2.02½.

Any insight or suggestions here would be very much appreciated!


回答1:


Unicode only supports a small number of vulgar fractions so a simple lookup table will do the trick:

# You might want to double check this mapping
vulgar_to_float = {
    "\u00BC" => 1.0 / 4.0,
    "\u00BD" => 1.0 / 2.0,
    "\u00BE" => 3.0 / 4.0,
    "\u2150" => 1.0 / 7.0,
    "\u2151" => 1.0 / 9.0,
    "\u2152" => 1.0 /10.0,
    "\u2153" => 1.0 / 3.0,
    "\u2154" => 2.0 / 3.0,
    "\u2155" => 1.0 / 5.0,
    "\u2156" => 2.0 / 5.0,
    "\u2157" => 3.0 / 5.0,
    "\u2158" => 4.0 / 5.0,
    "\u2159" => 1.0 / 6.0,
    "\u215A" => 5.0 / 6.0,
    "\u215B" => 1.0 / 8.0,
    "\u215C" => 3.0 / 8.0,
    "\u215D" => 5.0 / 8.0,
    "\u215E" => 7.0 / 8.0,
    "\u2189" => 0.0 / 3.0,
}

Then, a little bit of regex wrangling to pull your "number" apart:

s = "2½"
_, int_part, vulgar_part = *s.match(/(\d+)?(\D+)?/)

And finally, put them together taking care to properly deal with possible nils from the regex:

float_version = int_part.to_i + vulgar_to_float[vulgar_part].to_f

Remember that nil.to_i is 0 and nil.to_f is 0.0.




回答2:


Substitute the halves with ".5"

input = "2½"
input.gsub!("½", ".5")
input.to_f # => 2.5

As an aside, make sure you really want to use floats and not something like BigDecimal.

Here is a page explaining the problem with floats (it's Python, but Ruby and many other languages represent floats the same way, and thus have the same issues).




回答3:


Similar to @muistooshort's answer, I'd use a hash as a lookup table, but I'd take advantage of sub:

# encoding: UTF-8

LOOKUP = {
  "½" => 1.0/2,
  # ...
  "⅞" => 7.0/8,
}

LOOKUP_REGEX = Regexp.union(LOOKUP.keys) # => /½|⅞/ 

'2½'.sub(LOOKUP_REGEX) { |m| LOOKUP[m].to_s[1..-1] } # => "2.5" 
'2⅞'.sub(LOOKUP_REGEX) { |m| LOOKUP[m].to_s[1..-1] } # => "2.875" 

To make it more convenient and prettier:

class String
  def v_to_f
    sub(LOOKUP_REGEX) { |m| LOOKUP[m].to_s[1..-1] }
  end
end

'2½'.v_to_f # => "2.5" 
'2⅞'.v_to_f # => "2.875" 


来源:https://stackoverflow.com/questions/9051560/converting-string-2%c2%bd-two-and-a-half-into-2-5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!